package com.yutou.bilibili.Tools;

import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.DatatypeConverter;
import java.io.*;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;

public class AppTools {
    public static boolean saveFile(File file, String data){
        try {
            FileWriter writer=new FileWriter(file);
            writer.write(data);
            writer.flush();
            writer.close();
            return true;
        } catch (IOException e) {
            com.yutou.bilibili.Tools.Log.e(e);
            return false;
        }
    }
    public static String readFile(File file){
        try {
            BufferedReader reader=new BufferedReader(new FileReader(file));
            String tmp;
            StringBuilder str= new StringBuilder();
            while ((tmp=reader.readLine())!=null){
                str.append(tmp);
            }
            reader.close();
            return str.toString();
        } catch (Exception ignored) {
        }
        return null;
    }
    /**
     * 获取项目路径
     *
     * @param request
     * @return
     */
    public static String getPath(HttpServletRequest request) {
        return request.getServletContext().getRealPath("/") + "/";
    }
    public static String getToDayTime() {
        return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
    } public static String getToDayTime(Date date) {
        return new SimpleDateFormat("yyyy-MM-dd").format(date);
    }
    public static Date getToDayStartTime(){
        return   new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(AppTools.getToDayTime() + " " + "00:00",new ParsePosition(0));
    }
    public static Date getToDayNowTime(){
        return new Date();
    }
    public static String getToDayNowTimeToString(){
        return  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }
    public static String getToDayTimeToString(Date date){
        return  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
    }


    public static Map<String,String> getUrlParams(String url){
        Map<String,String> map=new HashMap<>();
        if(url.contains("?")){
            String param=url.split("\\?")[1];
            String[] params=param.split("&");
            for (String par : params) {
                map.put(par.split("=")[0],par.split("=")[1]);
            }
        }
        return map;
    }
    /**
     * N以内的不重复随机数
     *
     * @param min 最小值
     * @param max 最大值
     * @param n
     * @return
     */
    public static int[] randomCommon(int min, int max, int n) {
        int len = max - min + 1;
        if (max < min || n > len) {
            return new int[0];
        }
        // 初始化给定范围的待选数组
        int[] source = new int[len];
        for (int i = min; i < min + len; i++) {
            source[i - min] = i;
        }
        int[] result = new int[n];
        Random rd = new Random();
        int index = 0;
        for (int i = 0; i < result.length; i++) {
            // 待选数组0到(len-2)随机一个下标
            index = Math.abs(rd.nextInt() % len--);
            // 将随机到的数放入结果集
            result[i] = source[index];
            // 将待选数组中被随机到的数，用待选数组(len-1)下标对应的数替换
            source[index] = source[len];
        }
        return result;
    }
    /**
     * 设置Cookie
     *
     * @param response
     * @param key
     * @param value
     * @param time
     */
    public static void setCookie(HttpServletResponse response, String key, String value, int time) {
        Cookie cookie = new Cookie(key, value);
        if (time == -1) {
            time= 31536000;
        }
        cookie.setMaxAge(time);
        cookie.setPath("/");
        response.addCookie(cookie);

    }

    /**
     * 获取Cookie
     *
     * @param request
     * @param key
     * @return
     */
    public static Cookie getCookie(HttpServletRequest request, String key) {
        Cookie[] cookies = request.getCookies();
        try {
            for (Cookie cookie : cookies) {
                if (key != null && cookie.getName().equals(key)) {
                    return cookie;
                }
            }
        } catch (Exception ignored) {

        }

        return null;
    }

    /**
     * 删除Cookie
     *
     * @param request
     * @param response
     * @param key
     * @return
     */
    public static String deleteCookie(HttpServletRequest request, HttpServletResponse response, String key) {
        for (Cookie cookie : request.getCookies()) {
            if (cookie.getName().equals(key)) {
                com.yutou.bilibili.Tools.Log.i("删除key=" + key);
                cookie.setMaxAge(0);
                cookie.setPath("/");
                cookie.setValue(null);
                response.addCookie(cookie);
            }
        }
        return "ok";
    }
    public static String alphabetsInUpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    public static String alphabetsInLowerCase = "abcdefghijklmnopqrstuvwxyz";
    public static String numbers = "0123456789";
    public static String randomString(int length) {
        return randomString(length,new String[]{alphabetsInLowerCase,alphabetsInUpperCase,numbers});
    }
    public static String randomString(int length,String[] strs){
        String allCharacters="";
        for (String str : strs) {
            allCharacters+=str;
        }
        // create a super set of all characters
        // initialize a string to hold result
        StringBuffer randomString = new StringBuffer();
        // loop for 10 times
        for (int i = 0; i < length; i++) {
            // generate a random number between 0 and length of all characters
            int randomIndex = (int)(Math.random() * allCharacters.length());
            // retrieve character at index and add it to result
            randomString.append(allCharacters.charAt(randomIndex));
        }
        return randomString.toString();
    }
    public static String getLoginToken(HttpServletRequest request){
        String token = request.getParameter("token");
        if(StringUtils.isEmpty(token)){
            Cookie cookie=AppTools.getCookie(request,"login");
            if(cookie!=null){
                token=cookie.getValue();
            }
        }
        return token;
    }
    public static List<File> scanFilePath(String path){
        Log.i("scan > "+path);
        List<File> files=new ArrayList<>();
        File file=new File(path);
        for (File listFile : Objects.requireNonNull(file.listFiles())) {
            if(listFile.isDirectory()){
                files.addAll(scanFilePath(listFile.getAbsolutePath()));
            }else{
                files.add(listFile);
                Log.i("add file is > "+listFile.getAbsolutePath());
            }
        }
        return files;
    }
    /**
     * 构造给前端的文件
     *
     * @param file 文件路径
     * @return 前端获取的文件
     */
    public static ResponseEntity<FileSystemResource> getFile(File file) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        try {
            headers.add("Content-Disposition", "attachment; filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            headers.add("Content-Disposition", "attachment; filename=" + file.getName());
        }
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Last-Modified", new Date().toString());
        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
        return ResponseEntity.ok().headers(headers).contentLength(file.length()).contentType(MediaType.parseMediaType("application/octet-stream")).body(new FileSystemResource(file));
    }

    public static String getMD5(String data) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update(data.getBytes());
            return DatatypeConverter.printHexBinary(digest.digest());
        } catch (Exception e) {
            com.yutou.bilibili.Tools.Log.e(e);
        }
        return "";
    }

    public static boolean copyFileToName(String srcFileName,String destFileName,String fileName,boolean overlay) {
        File srcFile = new File(srcFileName);
        // 判断源文件是否存在
        if (!srcFile.exists()) {
            System.err.println("源文件不存在："+srcFile.getAbsolutePath()+"  >  "+destFileName);
            return false;
        } else if (!srcFile.isFile()) {
            System.err.println("源文件是目录:"+srcFile.getAbsolutePath());
            return false;
        }

        // 判断目标文件是否存在
        File destFile = new File(destFileName);
        // 如果目标文件所在目录不存在，则创建目录
        if (!destFile.exists()) {
            // 目标文件所在目录不存在
            if (!destFile.mkdirs()) {
                // 复制文件失败：创建目标文件所在目录失败
                System.err.println("创建文件夹失败:"+destFile.getAbsolutePath());
                return false;
            }

        }else{
            if(srcFileName.equals("Activity.smali")){
                com.yutou.bilibili.Tools.Log.i("文件夹已存在："+destFileName);
            }
        }

        // 复制文件
        int byteread = 0; // 读取的字节数
        InputStream in = null;
        OutputStream out = null;

        try {
            if(fileName==null) {
                fileName=srcFile.getName();
            }
            in = new FileInputStream(srcFile);
            out = new FileOutputStream(destFile + File.separator +fileName );
            byte[] buffer = new byte[1024];

            while ((byteread = in.read(buffer)) != -1) {
                out.write(buffer, 0, byteread);
            }
            out.close();
            in.close();
            return true;
        } catch (FileNotFoundException e) {
            com.yutou.bilibili.Tools.Log.e(e);
            return false;
        } catch (IOException e) {
            com.yutou.bilibili.Tools.Log.e(e);
            return false;
        }
    }

    public static boolean isRuntimeSystemOfWindow(){
        return  System.getProperty ("os.name").contains("Windows");
    }

    public static Process exec(String exec)throws Exception{
        if(AppTools.isRuntimeSystemOfWindow()) {
            return Runtime.getRuntime().exec(new String[]{
                            "cmd",
                            "/c",
                            exec
                    }
            );
        }else{
            return Runtime.getRuntime().exec(new String[]{
                            "sh",
                            "-c",
                            exec
                    }
            );
        }
    }
}
