package net.geedge.common;

import cn.hutool.core.io.IORuntimeException;
import cn.hutool.log.Log;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

public class T {
    /**
     * 时间工具类
     */
    public static class DateUtil extends cn.hutool.core.date.DateUtil {
    }

    /**
     * 字符串工具类
     */
    public static class StrUtil extends cn.hutool.core.util.StrUtil {
    }
    /**
     * 反射工具类
     *
     * @author Looly
     * @since 3.0.9
     */
    public static class ReflectUtil extends cn.hutool.core.util.ReflectUtil {
    }

    /**
     * Map相关工具类
     */
    public static class MapUtil extends cn.hutool.core.map.MapUtil {
    }

    /**
     * 集合工具类
     */
    public static class ListUtil extends cn.hutool.core.collection.ListUtil {
    }
    /**
     * 字符集工具类
     *
     * @author xiaoleilu
     */
    public static class CharsetUtil extends cn.hutool.core.util.CharsetUtil {
    }
    /**
     * ID生成器工具类，此工具类中主要封装：
     *
     * <pre>
     * 1. 唯一性ID生成器：UUID、ObjectId（MongoDB）、Snowflake
     * </pre>
     *
     * <p>
     * ID相关文章见：http://calvin1978.blogcn.com/articles/uuid.html
     *
     * @author looly
     * @since 4.1.13
     */
    public static class IdUtil extends cn.hutool.core.util.IdUtil {
    }
    /**
     * 线程池工具
     *
     * @author luxiaolei
     */
    public static class ThreadUtil extends cn.hutool.core.thread.ThreadUtil {
    }
    /**
     * json 工具类
     */
    public static class JSONUtil extends cn.hutool.json.JSONUtil {
    }
    /**
     * 系统运行时工具类，用于执行系统命令的工具
     *
     * @author Looly
     * @since 3.1.1
     */
    public static class RuntimeUtil extends cn.hutool.core.util.RuntimeUtil {
    }

    /**
     * 文件工具类
     *
     * @author looly
     */
    public static class FileUtil extends cn.hutool.core.io.FileUtil {
    }
    /**
     * 压缩工具类
     *
     * @author Looly
     */
    public static class ZipUtil extends cn.hutool.core.util.ZipUtil {
    }
    /**
     * IO工具类<br>
     * IO工具类只是辅助流的读写，并不负责关闭流。原因是流可能被多次读写，读写关闭后容易造成问题。
     *
     * @author xiaoleilu
     */
    public static class IoUtil extends cn.hutool.core.io.IoUtil {
    }
    /**
     * URL（Uniform Resource Locator）统一资源定位符相关工具类
     *
     * <p>
     * 统一资源定位符，描述了一台特定服务器上某资源的特定位置。
     * </p>
     * URL组成：
     *
     * <pre>
     *   协议://主机名[:端口]/ 路径/[:参数] [?查询]#Fragment
     *   protocol :// hostname[:port] / path / [:parameters][?query]#fragment
     * </pre>
     *
     * @author xiaoleilu
     */
    public static class URLUtil extends cn.hutool.core.util.URLUtil {
    }

    /**
     * 对象工具类，包括判空、克隆、序列化等操作
     *
     * @author Looly
     */
    public static class ObjectUtil extends cn.hutool.core.util.ObjectUtil {
    }

    /**
     * CommandLineUtil
     *
     * @version org.apache.commons.commons-exec:1.3
     * @apiNote copy from rg.apache.commons.exec.CommandLine.translateCommandline
     */
    public static class CommandLineUtil {
        /**
         * translateCommandline
         *
         * @param toProcess
         * @return
         */
        public static String[] translateCommandline(String toProcess) {
            if (toProcess != null && toProcess.length() != 0) {
                int state = 0;
                StringTokenizer tok = new StringTokenizer(toProcess, "\"' ", true);
                ArrayList<String> list = new ArrayList();
                StringBuilder current = new StringBuilder();
                boolean lastTokenHasBeenQuoted = false;

                while (true) {
                    while (tok.hasMoreTokens()) {
                        String nextTok = tok.nextToken();
                        switch (state) {
                            case 1:
                                if ("'".equals(nextTok)) {
                                    lastTokenHasBeenQuoted = true;
                                    state = 0;
                                } else {
                                    current.append(nextTok);
                                }
                                continue;
                            case 2:
                                if ("\"".equals(nextTok)) {
                                    lastTokenHasBeenQuoted = true;
                                    state = 0;
                                } else {
                                    current.append(nextTok);
                                }
                                continue;
                        }

                        if ("'".equals(nextTok)) {
                            state = 1;
                        } else if ("\"".equals(nextTok)) {
                            state = 2;
                        } else if (" ".equals(nextTok)) {
                            if (lastTokenHasBeenQuoted || current.length() != 0) {
                                list.add(current.toString());
                                current = new StringBuilder();
                            }
                        } else {
                            current.append(nextTok);
                        }

                        lastTokenHasBeenQuoted = false;
                    }

                    if (lastTokenHasBeenQuoted || current.length() != 0) {
                        list.add(current.toString());
                    }

                    if (state != 1 && state != 2) {
                        String[] args = new String[list.size()];
                        return (String[]) list.toArray(args);
                    }

                    throw new IllegalArgumentException("Unbalanced quotes in " + toProcess);
                }
            } else {
                return new String[0];
            }
        }
    }

    public static class ResponseUtil {
        static Log log = Log.get();
        /**
         * reponse 下载 byte数据
         */
        public static void downloadFile(HttpServletResponse response, String filename, byte[] data) throws IORuntimeException, IOException {
            log.info("[downloadFile] [fileName: {}] [size: {}]", filename, data.length);
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            String fileName = T.URLUtil.encode(filename, T.CharsetUtil.CHARSET_UTF_8);
            cn.hutool.core.util.ReflectUtil.invoke(response, "addHeader", "Content-Disposition", "attachment; filename=" + fileName);
            cn.hutool.core.util.ReflectUtil.invoke(response, "addHeader", "Content-Length", "" + data.length);
            cn.hutool.core.util.ReflectUtil.invoke(response, "setHeader", "Access-Control-Expose-Headers", "Content-Disposition");
            T.IoUtil.write(response.getOutputStream(), false, data);
        }
    }

    public static class WebPathUtil {
        static Log log = Log.get();

        /**
         * 如果已打成jar包，则返回jar包所在目录
         * 如果未打成jar，则返回target所在目录
         *
         * @return
         */
        public static String getClassPath() {
            try {
                // 项目的编译文件的根目录
                String path = URLDecoder.decode(System.getProperty("user.dir"), "utf-8");
                log.debug("root path:{}", path);
                return path;
            } catch (UnsupportedEncodingException e) {
                return null;
            }
        }

        public static String getRootPath() {
            File file = T.FileUtil.file(WebPathUtil.getClassPath());
            return file.getAbsolutePath();
        }
    }

    public class DigestUtils {
        private static final List<String> ENCODE_LIST = Arrays.asList("ISO-8859-1", "GB2312", "UTF-8", "GBK");

        public static String getEncoding(String text) {
            for (String enc : ENCODE_LIST) {
                try {
                    byte[] bytes = text.getBytes(enc);
                    String str = cn.hutool.core.util.StrUtil.str(bytes, enc);
                    Arrays.fill(bytes, (byte) 0);
                    if (cn.hutool.core.util.StrUtil.equals(text, str)) {
                        return enc;
                    }
                } catch (UnsupportedEncodingException e) {
                }
            }
            return null;
        }
    }

}