package org.bdware.sc.encrypt;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

public class HardwareInfo {
    public static OSType type = getOSType();

    private static OSType getOSType() {
        String osName = System.getProperty("os.name") + " " + System.getProperty("os.version");
        System.out.println("[HardwareInfo] OS Name:" + osName);
        if (osName.startsWith("Mac")) return OSType.mac;
        else if (osName.startsWith("Linux")) {
            return OSType.linux;
        } else if (osName.contains("Windows")) {
            return OSType.win;
        }
        return OSType.unknown;
    }

    public static String getCPUID() {
        switch (type) {
            case mac:
                return getCPUID_Mac();
            case linux:
                return getCPUID_Linux();
            case win:
                return getCPUID_Windows();
            default:
                return "";
        }
    }

    public static String getCPUID_Windows() {
        try {
            Process process =
                    Runtime.getRuntime().exec(new String[]{"wmic", "cpu", "get", "ProcessorId"});
            process.getOutputStream().close();
            Scanner sc = new Scanner(process.getInputStream());
            String property = sc.next();
            String serial = sc.next();
            System.out.println(property + ": " + serial);

            sc.close();
            return serial;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static String getCPUID_Linux() {
        StringBuilder result = new StringBuilder();
        String CPU_ID_CMD = "dmidecode";
        BufferedReader bufferedReader;
        Process p;
        try {
            p = Runtime.getRuntime().exec(new String[]{"sh", "-c", CPU_ID_CMD}); // 管道
            bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            int index;
            while ((line = bufferedReader.readLine()) != null) {
                // 寻找标示字符串[hwaddr]
                index = line.toLowerCase().indexOf("uuid");
                if (index >= 0) { // 找到了
                    result = new StringBuilder(line.substring(index + "uuid".length() + 1).trim());
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("[HardwareInfo] get cpuInfo:" + result + "==");
        if (result.toString().equals("")) {
            try {
                p = Runtime.getRuntime().exec(new String[]{"dmesg"});
                Scanner sc = new Scanner(p.getInputStream());
                while (sc.hasNextLine()) {
                    String line = sc.nextLine();
                    if (line.contains("Kernel") && line.contains("UUID")) {
                        result = new StringBuilder(line.replaceAll(".*UUID=", ""));
                        result = new StringBuilder(result.toString().replaceAll(" .*$", ""));
                        break;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } // 管道
        }
        if (result.toString().equals("")) {
            Runtime rt = Runtime.getRuntime();
            try {
                Process proc = rt.exec("cat /sys/class/dmi/id/product_uuid");
                InputStreamReader isr = new InputStreamReader(proc.getInputStream());
                BufferedReader br = new BufferedReader(isr);
                String line;
                while ((line = br.readLine()) != null) {
                    result.append(line);
                }
                isr.close();
                result = new StringBuilder(result.toString().trim());
                result = new StringBuilder(result.toString().replace(" ", ""));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result.toString().trim();
    }

    // system_profiler SPHardwareDataType
    public static String getCPUID_Mac() {
        Process p;
        try {
            p =
                    Runtime.getRuntime()
                            .exec(
                                    new String[]{
                                            "system_profiler", "SPHardwareDataType",
                                    }); // 管道
            Scanner sc = new Scanner(p.getInputStream());
            while (sc.hasNextLine()) {
                String line = sc.nextLine();
                if (line.contains("Hardware UUID:")) {
                    line = line.replaceAll(".*:", "");
                    sc.close();
                    return line;
                }
            }
            sc.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    public enum OSType {
        mac,
        linux,
        win,
        unknown
    }
}
