package com.game.autotune;

import java.io.*;
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;

public class ConfigAutoTuner {
    private static final String TAG = "ConfigAutoTuner";
    
    // 游戏信息配置
    private final List<GameInfo> gameInfos = new CopyOnWriteArrayList<>();
    
    // 设备信息（Xiaomi 14 Pro示例）
    private volatile DeviceSpecs deviceSpecs = new DeviceSpecs(
        "Xiaomi 14 Pro",        // 设备型号
        "Snapdragon 8 Gen 3",   // CPU型号
        "Adreno 750",           // GPU型号
        12,                     // 内存大小(GB)
        15                      // 安卓版本
    );
    
    private final ScheduledExecutorService scheduler;
    private final Map<String, TuningResult> tuningResults = new ConcurrentHashMap<>();
    private final AtomicBoolean isRunning = new AtomicBoolean(false);
    private final Map<String, GamePerformanceHistory> performanceHistory = new ConcurrentHashMap<>();

    public ConfigAutoTuner() {
        this.scheduler = Executors.newScheduledThreadPool(2);
        initializeDefaultGameTemplate();
    }

    private void initializeDefaultGameTemplate() {
        // 添加和平精英游戏配置
        addGameInfo(new GameInfo(
            "和平精英",
            "com.tencent.tmgp.pubgmhd",
            "1.33.12",
            "BattleRoyale",
            "/sdcard/Android/data/com.tencent.tmgp.pubgmhd/files/UE4Game/ShadowTrackerExtra/ShadowTrackerExtra/Saved/Config/Android/GameUserSettings.ini",
            90,    // 目标帧率
            4      // 画质等级
        ));
    }

    // 设置设备信息
    public void setDeviceSpecs(String model, String cpu, String gpu, int ramGB, int androidVersion) {
        this.deviceSpecs = new DeviceSpecs(model, cpu, gpu, ramGB, androidVersion);
        System.out.println("设备信息已设置: " + model + " Android " + androidVersion);
    }

    // 添加游戏信息
    public void addGameInfo(GameInfo gameInfo) {
        gameInfos.add(gameInfo);
        performanceHistory.put(gameInfo.gameId, new GamePerformanceHistory(gameInfo.gameId));
        System.out.println("已添加游戏: " + gameInfo.gameName + " (" + gameInfo.gameId + ")");
    }

    // 开始自动优化
    public void startAutoTuning() {
        if (isRunning.getAndSet(true)) {
            System.out.println("优化服务已在运行中");
            return;
        }

        System.out.println("开始自动优化，设备: " + deviceSpecs.model + " (Android " + deviceSpecs.androidVersion + ")");
        
        // 立即执行一次优化
        tuneAllGames();
        
        // 定时检查并优化（每5分钟）
        scheduler.scheduleAtFixedRate(this::tuneAllGames, 5, 5, TimeUnit.MINUTES);
        
        // 性能监控（每2分钟）
        scheduler.scheduleAtFixedRate(this::monitorPerformance, 2, 2, TimeUnit.MINUTES);
    }

    private void tuneAllGames() {
        if (!isRunning.get()) return;
        
        for (GameInfo game : gameInfos) {
            tuneGameConfig(game);
        }
    }

    private void tuneGameConfig(GameInfo game) {
        try {
            Path configPath = Paths.get(game.configPath);
            if (!Files.exists(configPath)) {
                System.out.println("配置文件不存在: " + game.configPath);
                return;
            }

            // 备份原配置文件
            backupOriginalConfig(configPath);

            // 读取并优化配置
            Map<String, String> originalConfig = readConfigFile(configPath.toString());
            Map<String, String> tunedConfig = generateTunedConfig(game, originalConfig);
            
            // 保存优化配置
            saveTunedConfig(configPath.toString(), tunedConfig);
            
            // 记录优化结果
            TuningResult result = new TuningResult(
                game.gameId, game.gameName, new Date(), "pending", tunedConfig.size()
            );
            tuningResults.put(game.gameId, result);

            System.out.println("已优化: " + game.gameName + " (" + tunedConfig.size() + " 个参数)");

        } catch (Exception e) {
            System.err.println("优化失败 " + game.gameName + ": " + e.getMessage());
        }
    }

    private Map<String, String> readConfigFile(String path) throws IOException {
        Map<String, String> config = new LinkedHashMap<>();
        
        if (path.endsWith(".ini")) {
            return readIniFile(path);
        } else if (path.endsWith(".json")) {
            return readJsonFile(path);
        } else {
            throw new IOException("不支持的配置文件格式: " + path);
        }
    }

    private Map<String, String> readIniFile(String path) throws IOException {
        Map<String, String> config = new LinkedHashMap<>();
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(new FileInputStream(path), StandardCharsets.UTF_8))) {
            
            String line;
            String currentSection = "";
            while ((line = br.readLine()) != null) {
                line = line.trim();
                if (line.isEmpty() || line.startsWith(";")) continue;
                
                if (line.startsWith("[") && line.endsWith("]")) {
                    currentSection = line.substring(1, line.length() - 1) + ".";
                } else if (line.contains("=")) {
                    String[] parts = line.split("=", 2);
                    if (parts.length == 2) {
                        String key = currentSection + parts[0].trim();
                        config.put(key, parts[1].trim());
                    }
                }
            }
        }
        return config;
    }

    private Map<String, String> generateTunedConfig(GameInfo game, Map<String, String> original) {
        Map<String, String> tuned = new LinkedHashMap<>(original);
        
        // 设备性能适配
        applyDeviceSpecificOptimizations(game, tuned);
        
        // 安卓版本特定优化
        applyAndroidVersionOptimizations(tuned);
        
        // 游戏特定优化
        applyGameSpecificOptimizations(game, tuned);
        
        return tuned;
    }

    private void applyDeviceSpecificOptimizations(GameInfo game, Map<String, String> config) {
        // 根据内存调整画质
        int qualityLevel = calculateOptimalQuality(game.recommendedQuality);
        config.put("QualityLevel", String.valueOf(qualityLevel));
        
        // 根据设备性能调整帧率
        int targetFPS = calculateOptimalFPS(game.recommendedFps);
        config.put("FrameRateLimit", String.valueOf(targetFPS));
        config.put("MaxFPS", String.valueOf(targetFPS));
        
        // 高端设备专用设置
        if (deviceSpecs.ramGB >= 12) {
            config.put("r.PUBG.HighEndDevice", "1");
            config.put("r.PUBG.EnableHighQualityEffects", "1");
        }
    }

    private void applyAndroidVersionOptimizations(Map<String, String> config) {
        // Android 15专属优化
        config.put("Android15_Optimized", "true");
        config.put("GraphicsAPI", "Vulkan");
        config.put("EnablePredictiveRendering", "true");
        config.put("r.Android.UseParallelRendering", "1");
        
        config.put("LastOptimized", new Date().toString());
        config.put("OptimizedFor", deviceSpecs.model);
    }

    private void applyGameSpecificOptimizations(GameInfo game, Map<String, String> config) {
        // 和平精英特定优化
        if (game.gameId.equals("com.tencent.tmgp.pubgmhd")) {
            // 基础优化
            config.put("MobileContentScaleFactor", "0");
            config.put("EnableGPUCrashDebugging", "false");
            config.put("UseVulkan", "true");
            config.put("r.PUBG.Android15.Optimization", "1");
            config.put("r.Android.DisableBufferAge", "1");
            
            // 画质设置
            config.put("r.PUBG.RenderQuality", "4");
            config.put("r.PUBG.ShadowQuality", "2");
            config.put("r.PUBG.EffectQuality", "3");
            config.put("r.PUBG.PostProcessQuality", "3");
            config.put("r.PUBG.TextureQuality", "4");
            
            // 帧率设置
            config.put("r.PUBG.FrameRate", "90");
            config.put("r.PUBG.MaxFPS", "90");
            config.put("r.PUBG.DynamicFPS", "0");
            
            // 1.33.12版本特定优化
            if (game.version.equals("1.33.12")) {
                config.put("r.PUBG.Version13312.Optimization", "1");
                config.put("r.PUBG.NewAntiAliasing", "1");
                config.put("r.PUBG.EnableNewWaterEffect", "0"); // 关闭新版水面效果提升性能
            }
        }
    }

    private int calculateOptimalQuality(int baseQuality) {
        if (deviceSpecs.ramGB >= 12) return Math.min(baseQuality + 1, 5);
        if (deviceSpecs.ramGB >= 8) return baseQuality;
        if (deviceSpecs.ramGB >= 6) return Math.max(baseQuality - 1, 2);
        return Math.max(baseQuality - 2, 1);
    }

    private int calculateOptimalFPS(int baseFPS) {
        if (deviceSpecs.ramGB >= 8 && deviceSpecs.androidVersion >= 14) {
            return Math.min(baseFPS + 10, 120);
        }
        return baseFPS;
    }

    private void saveTunedConfig(String path, Map<String, String> config) throws IOException {
        Path configPath = Paths.get(path);
        Path backupPath = configPath.getParent().resolve(configPath.getFileName() + ".backup");
        
        // 确保有备份
        if (!Files.exists(backupPath)) {
            Files.copy(configPath, backupPath, StandardCopyOption.REPLACE_EXISTING);
        }

        if (path.endsWith(".ini")) {
            saveIniConfig(path, config);
        }
    }

    private void saveIniConfig(String path, Map<String, String> config) throws IOException {
        try (BufferedWriter bw = new BufferedWriter(
                new OutputStreamWriter(new FileOutputStream(path), StandardCharsets.UTF_8))) {
            
            String currentSection = "";
            for (Map.Entry<String, String> entry : config.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                
                if (key.contains(".")) {
                    String[] parts = key.split("\\.", 2);
                    String newSection = parts[0];
                    if (!newSection.equals(currentSection)) {
                        if (!currentSection.isEmpty()) bw.newLine();
                        bw.write("[" + newSection + "]");
                        bw.newLine();
                        currentSection = newSection;
                    }
                    bw.write(parts[1] + "=" + value);
                } else {
                    bw.write(key + "=" + value);
                }
                bw.newLine();
            }
        }
    }

    private void backupOriginalConfig(Path configPath) throws IOException {
        Path backupPath = configPath.getParent().resolve(configPath.getFileName() + ".backup");
        if (!Files.exists(backupPath)) {
            Files.copy(configPath, backupPath, StandardCopyOption.REPLACE_EXISTING);
        }
    }

    private void monitorPerformance() {
        if (!isRunning.get()) return;
        
        tuningResults.forEach((gameId, result) -> {
            float effectiveness = simulatePerformanceCheck(gameId);
            updateTuningEffectiveness(gameId, effectiveness);
        });
    }

    private float simulatePerformanceCheck(String gameId) {
        // 模拟性能评分（8.5-9.5之间）
        return 8.5f + new Random().nextFloat();
    }

    private void updateTuningEffectiveness(String gameId, float effectiveness) {
        TuningResult result = tuningResults.get(gameId);
        if (result != null) {
            result.effectiveness = String.format("%.1f/10", effectiveness);
            
            if (effectiveness < 7.0f) {
                System.out.println("优化效果不佳 (" + effectiveness + "/10)，准备重新优化: " + result.gameName);
                GameInfo game = gameInfos.stream()
                    .filter(g -> g.gameId.equals(gameId))
                    .findFirst()
                    .orElse(null);
                if (game != null) {
                    scheduler.schedule(() -> tuneGameConfig(game), 30, TimeUnit.SECONDS);
                }
            }
        }
    }

    public void stopTuning() {
        if (isRunning.getAndSet(false)) {
            scheduler.shutdown();
            try {
                if (!scheduler.awaitTermination(10, TimeUnit.SECONDS)) {
                    scheduler.shutdownNow();
                }
            } catch (InterruptedException e) {
                scheduler.shutdownNow();
                Thread.currentThread().interrupt();
            }
            System.out.println("自动优化服务已停止");
        }
    }

    public void printCurrentStatus() {
        System.out.println("=== 自动优化器状态 ===");
        System.out.println("设备: " + deviceSpecs.model + " Android " + deviceSpecs.androidVersion);
        System.out.println("已监控游戏: " + gameInfos.size());
        System.out.println("运行状态: " + (isRunning.get() ? "运行中" : "已停止"));
        
        tuningResults.forEach((gameId, result) -> {
            System.out.println("游戏: " + result.gameName + " - 效果: " + result.effectiveness);
        });
    }

    // 游戏信息类
    public static class GameInfo {
        public final String gameName;
        public final String gameId;  
        public final String version;
        public final String genre;
        public final String configPath;
        public final int recommendedFps;
        public final int recommendedQuality;

        public GameInfo(String gameName, String gameId, String version, String genre, 
                       String configPath, int recommendedFps, int recommendedQuality) {
            this.gameName = gameName;
            this.gameId = gameId;
            this.version = version;
            this.genre = genre;
            this.configPath = configPath;
            this.recommendedFps = recommendedFps;
            this.recommendedQuality = recommendedQuality;
        }
    }

    // 设备规格类
    public static class DeviceSpecs {
        public final String model;
        public final String cpu;
        public final String gpu;
        public final int ramGB;
        public final int androidVersion;

        public DeviceSpecs(String model, String cpu, String gpu, int ramGB, int androidVersion) {
            this.model = model;
            this.cpu = cpu;
            this.gpu = gpu;
            this.ramGB = ramGB;
            this.androidVersion = androidVersion;
        }
    }

    // 优化结果类
    private static class TuningResult {
        String gameId;
        String gameName;
        Date tuneTime;
        String effectiveness;
        int tunedParameters;

        TuningResult(String gameId, String gameName, Date tuneTime, String effectiveness, int tunedParameters) {
            this.gameId = gameId;
            this.gameName = gameName;
            this.tuneTime = tuneTime;
            this.effectiveness = effectiveness;
            this.tunedParameters = tunedParameters;
        }
    }

    // 游戏性能历史记录
    private static class GamePerformanceHistory {
        String gameId;
        List<Float> performanceScores = new ArrayList<>();
        Date lastUpdated;

        GamePerformanceHistory(String gameId) {
            this.gameId = gameId;
            this.lastUpdated = new Date();
        }
    }

    public static void main(String[] args) {
        ConfigAutoTuner tuner = new ConfigAutoTuner();
        tuner.startAutoTuning();
        
        // 示例：运行30秒后停止
        try {
            TimeUnit.SECONDS.sleep(30);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        tuner.printCurrentStatus();
        tuner.stopTuning();
    }
}
