package com.priusis.cache;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yangli
 * @since 2021/09/22
 */
@Component
public class InstalledProgramCache {

    private static List<Map<String, String>> programList;

    public List<Map<String, String>> getPrograms() throws IOException {
        if (programList == null) loadProgramListJob();
        return programList;
    }


    @Scheduled(fixedDelay = 3000)
    protected void loadProgramListJob() throws IOException {
        List<Map<String, String>> programs = new ArrayList<>();
        Process process = Runtime.getRuntime()
                .exec("cmd /c reg query HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"))) {
            String key;
            while ((key = reader.readLine()) != null) {
                Map<String, String> info = queryProgramInfo(key);
                if (info.containsKey("name")) programs.add(info);
            }
            process.destroy();
        }
        programList = programs;
    }

    private Map<String, String> queryProgramInfo(String key) throws IOException {
        Map<String, String> info = new HashMap<>();
        Process process = Runtime.getRuntime().exec("cmd /c reg query " + key);
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"))) {
            reader.readLine();
            reader.readLine();
            String line;
            while ((line = reader.readLine()) != null) {
                line = line.trim();
                if (line.startsWith("DisplayName")) {
                    info.put("name", line.replace("DisplayName", "").replace("REG_SZ", "").trim());
                } else if (line.startsWith("DisplayVersion")) {
                    info.put("version", line.replace("DisplayVersion", "").replace("REG_SZ", "").trim());
                } else if (line.startsWith("InstallLocation")) {
                    info.put("path", line.replace("InstallLocation", "").replace("REG_SZ", "").trim());
                }
            }
            process.destroy();
        }
        return info;
    }
}
