package me.qwq.doghouse.util;

import java.io.IOException;
import java.nio.file.*;

public final class OSUtils {

    private static final String OS = System.getProperty("os.name").toLowerCase();
    private static final boolean IS_WINDOWS = OS.contains("win");
    private static final boolean IS_MAC = OS.contains("mac");
    private static final boolean IS_LINUX = OS.contains("nux") || OS.contains("nix");
    private static Boolean isCaseSensitiveFS = null;
    
    private OSUtils() {}

    /* ------------------------------
     * 1. 系统识别
     * ------------------------------ */

    public static boolean isWindows() {
        return IS_WINDOWS;
    }

    public static boolean isMac() {
        return IS_MAC;
    }

    public static boolean isLinux() {
        return IS_LINUX;
    }

    /** 是否类 Unix（Linux + macOS + FreeBSD 等） */
    public static boolean isUnixLike() {
        return IS_LINUX || IS_MAC;
    }

    /** 返回当前 OS 友好的名字 */
    public static String getFriendlyOSName() {
        if (IS_WINDOWS) return "Windows";
        if (IS_MAC) return "macOS";
        if (IS_LINUX) return "Linux";
        return OS;
    }


    /* ------------------------------
     * 2. 文件名合法性（根据 OS 判断）
     * ------------------------------ */

    /** 判断文件名是否合法，不包含路径 */
    public static boolean isValidFileName(String name) {
        if (name == null || name.trim().isEmpty()) return false;

        String trimmed = name.trim();

        // 不允许包含路径分隔符
        if (trimmed.contains("/") || trimmed.contains("\\")) {
            return false;
        }

        if (IS_WINDOWS) {
            return isValidWindowsFileName(trimmed);
        } else {
            return isValidUnixFileName(trimmed);
        }
    }

    private static boolean isValidWindowsFileName(String name) {
        String illegal = "\\/:*?\"<>|";
        for (char c : illegal.toCharArray()) {
            if (name.indexOf(c) >= 0) return false;
        }

        if (name.endsWith(".") || name.endsWith(" ")) return false;

        String upper = name.toUpperCase();
        String[] reserved = {
                "CON", "PRN", "AUX", "NUL",
                "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
                "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"
        };
        for (String r : reserved) {
            if (upper.equals(r)) return false;
        }
        return true;
    }

    private static boolean isValidUnixFileName(String name) {
        // Linux/macOS 仅禁止 0x00 和 '/'
        return name.indexOf('/') < 0 && name.indexOf('\0') < 0;
    }


    /* ------------------------------
     * 3. 判断文件系统是否大小写敏感
     * ------------------------------ */

    /**
     * 判断当前文件系统是否大小写敏感
     * macOS 默认不敏感，Linux 默认敏感，Windows 不敏感
     * 但该函数会实际检测文件系统，适用于挂载特殊卷（如 APFS case-sensitive）
     */
    public static Boolean isCaseSensitiveFS() {
        if (isCaseSensitiveFS != null) {
            return isCaseSensitiveFS;
        }
        try {
            Path tmpDir = Files.createTempDirectory("case-test");
            Path a = tmpDir.resolve("testFile");
            Path b = tmpDir.resolve("testfile");

            Files.createFile(a);
            isCaseSensitiveFS = !Files.exists(b);

            Files.deleteIfExists(a);
            Files.deleteIfExists(b);
            Files.deleteIfExists(tmpDir);
            return isCaseSensitiveFS;

        } catch (IOException e) {
            // 回退逻辑（常规 OS 假设）
            if (IS_WINDOWS) return false;
            if (IS_MAC) return false; // 大多数 mac 文件系统不敏感
            return true; // Linux 常常敏感
        }
    }


    /* ------------------------------
     * 4. 路径相关工具
     * ------------------------------ */

    /** 判断是否为绝对路径 */
    public static boolean isAbsolutePath(String path) {
        if (path == null) return false;
        return Paths.get(path).isAbsolute();
    }

    /** 统一路径拼接 */
    public static Path join(Path base, String child) {
        return base.resolve(child);
    }

    /** 判断路径是否可写 */
    public static boolean isWritablePath(Path path) {
        try {
            if (!Files.exists(path)) {
                Files.createDirectories(path);
            }
            Path tmp = path.resolve(".perm-test");
            Files.write(tmp, "x".getBytes());
            Files.delete(tmp);
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    /* ------------------------------
     * 5. 获取推荐目录
     * ------------------------------ */

    public static Path getUserHome() {
        return Paths.get(System.getProperty("user.home"));
    }

    public static Path getTempDir() {
        return Paths.get(System.getProperty("java.io.tmpdir"));
    }

    public static Path getSafeDefaultStorage(String appName) {
        if (IS_WINDOWS) {
            return Paths.get(System.getenv("LOCALAPPDATA"), appName);
        } else {
            return Paths.get("/tmp", appName);
        }
    }
}
