package com.axis.innovators.box;

import com.axis.innovators.box.events.GlobalEventBus;
import com.axis.innovators.box.events.SettingsLoadEvents;
import com.axis.innovators.box.events.SubscribeEvent;
import com.axis.innovators.box.gui.*;
import com.axis.innovators.box.plugins.PluginLoader;
import com.axis.innovators.box.tools.LibraryLoad;
import com.axis.innovators.box.tools.SystemInfoUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.IOException;

/**
 * 主类
 * @author tzdwindows 7
 */
public class Main {
    private static final Logger logger = LogManager.getLogger(Main.class);
    private static final String VERSIONS = "0.0.1";
    private static final String[] AUTHOR = new String[]{
            "tzdwindows 7"
    };
    /** 我是总任务数 **/
    public static int totalTasks = 0;
    /** 我是当前任务数 **/
    public static int completedTasks = 0;
    public static ProgressBarManager progressBarManager = new ProgressBarManager("加载中...", totalTasks);

    static {
        try {
            LibraryLoad.loadLibrary("FridaNative");
        } catch (Exception e) {
            logger.error("Failed to load the 'FridaNative' library", e);
            throw new RuntimeException(e);
        }
    }

    @SubscribeEvent
    public void onSettingsLoad(SettingsLoadEvents event) {
        JLabel placeholder = new JLabel("设置功能开发中...", SwingConstants.CENTER);
        placeholder.setFont(new Font("微软雅黑", Font.PLAIN, 24));
        placeholder.setForeground(new Color(127, 140, 153));
        event.content().add(placeholder, BorderLayout.CENTER);

    }

    public static void main(String[] args) {
        Log4j2OutputStream.redirectSystemStreams();
        // 输出版本和作者信息
        logger.info("Application Version: {}", VERSIONS);
        logger.info("Authors: {}", String.join(", ", AUTHOR));

        // 输出系统信息
        logger.info("Operating System: {}", SystemInfoUtil.getOSName());
        logger.info("OS Architecture: {}", SystemInfoUtil.getOSArch());
        logger.info("CPU: {}", SystemInfoUtil.getCPUInfo());
        logger.info("GPU: {}", SystemInfoUtil.getGPUInfo());
        logger.info("Java Version: {}", System.getProperty("java.version"));
        logger.info("Java Vendor: {}", System.getProperty("java.vendor"));
        logger.info("Java Home: {}", System.getProperty("java.home"));
        logger.info("Java Class Path: {}", System.getProperty("java.class.path"));
        logger.info("ClassLoader.getSystemClassLoader(): {}", ClassLoader.getSystemClassLoader());

        // 注册事件
        GlobalEventBus.EVENT_BUS.register(new Main());

        // 设置系统外观
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            logger.warn("Failed to load the system facade class", e);
        }
        Thread thread = new Thread(() -> {
            try {
                // 主任务1：加载插件
                progressBarManager.updateMainProgress(++completedTasks);
                PluginLoader.loadPlugins();
                logger.info("Loaded plugins");

                progressBarManager.close();

                SwingUtilities.invokeLater(() -> {
                    try {
                        MainWindow ex = new MainWindow();
                        int id = 0;
                        MainWindow.ToolCategory debugCategory = new MainWindow.ToolCategory("调试工具",
                                "debug/debug.png",
                                "用于调试指定Windows工具的一个分类");

                        debugCategory.addTool(new MainWindow.ToolItem("Frida注入工具", "debug/frida/frida_main.png",
                                "使用frida注入目标进程的脚本程序 " +
                                        "\n作者：tzdwindows 7", ++id, new AbstractAction() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                Window owner = SwingUtilities.windowForComponent((Component) e.getSource());
                                FridaWindow fridaWindow = new FridaWindow(owner);
                                fridaWindow.setVisible(true);
                            }
                        }));

                        ex.addToolCategory(debugCategory);

                        MainWindow.ToolCategory aICategory = new MainWindow.ToolCategory("AI工具",
                                "ai/ai.png",
                                "人工智能/大语言模型");

                        aICategory.addTool(new MainWindow.ToolItem("本地AI执行工具", "ai/local/local_main.png",
                                "在本机对开源大语言模型进行推理" +
                                        "\n作者：tzdwindows 7", ++id, new AbstractAction() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                Window owner = SwingUtilities.windowForComponent((Component) e.getSource());
                                LocalWindow dialog = new LocalWindow(owner);
                                dialog.setVisible(true);
                            }
                        }));

                        ex.addToolCategory(aICategory);

                        ex.initUI();
                        ex.setVisible(true);
                    } catch (Exception e) {
                        logger.error("There was a problem starting the main thread", e);
                        throw new RuntimeException(e);
                    }
                });
            } catch (Exception e) {
                logger.error("Failed to load plugins", e);
                throw new RuntimeException(e);
            }
        });
        thread.setName("Main Thread");
        thread.start();
    }
}