#!/usr/bin/env node

/**
 * Pixiv 后端服务器启动脚本
 */

const fs = require('fs');
const path = require('path');
const os = require('os');

// 只在 Windows 环境下设置终端标题
if (os.platform() === 'win32') {
  process.title = 'Pixiv Manager';
}

// 加载配置文件
function loadConfig() {
  // 检测是否在pkg打包环境中运行
  const isPackaged = process.pkg !== undefined;
  
  // 在打包环境中，配置文件在当前工作目录；在开发环境中，配置文件在上级目录
  const configPath = isPackaged 
    ? path.join(process.cwd(), 'config.json')  // 打包环境：当前工作目录
    : path.join(__dirname, '..', 'config.json');  // 开发环境：上级目录
  let config = {
    server: {
      port: 3000,
      autoOpenBrowser: true
    },
    proxy: {
      port: null,
      enabled: false
    },
    logging: {
      level: "INFO"
    },
    system: {
      threadPoolSize: 16
    }
  };

  try {
    console.log(`检测环境: ${isPackaged ? '打包环境' : '开发环境'}`);
    console.log(`配置文件路径: ${configPath}`);
    
    if (fs.existsSync(configPath)) {
      const configData = fs.readFileSync(configPath, 'utf8');
      const userConfig = JSON.parse(configData);
      
      // 合并配置，用户配置覆盖默认配置
      config = {
        ...config,
        server: { ...config.server, ...userConfig.server },
        proxy: { ...config.proxy, ...userConfig.proxy },
        logging: { ...config.logging, ...userConfig.logging },
        system: { ...config.system, ...userConfig.system }
      };
      console.log('已加载配置文件');
    } else {
      // 如果配置文件不存在，创建默认配置文件
      fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
      console.log('已创建默认配置文件:', configPath);
    }
  } catch (error) {
    console.error('读取配置文件失败，使用默认配置:', error.message);
  }

  return config;
}

// 获取Windows系统代理配置
function getWindowsProxy() {
  if (os.platform() !== 'win32') return null;
  
  try {
    const { execSync } = require('child_process');
    // 查询注册表获取代理设置
    const output = execSync('reg query "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"', { encoding: 'utf8' });
    
    // 检查代理是否启用 (ProxyEnable = 1)
    const proxyEnableMatch = output.match(/ProxyEnable\s+REG_DWORD\s+0x([0-9a-fA-F]+)/);
    if (proxyEnableMatch && parseInt(proxyEnableMatch[1], 16) === 1) {
      // 获取代理服务器地址
      const proxyServerMatch = output.match(/ProxyServer\s+REG_SZ\s+([^\r\n]+)/);
      if (proxyServerMatch) {
        return proxyServerMatch[1];
      }
    }
  } catch (error) {
    // 忽略错误，可能没有权限或键不存在
  }
  return null;
}

// 加载配置
const config = loadConfig();

// 重要：必须在任何其他模块导入之前设置线程池大小
// 解决多个下载任务时的SSH连接阻塞问题
if (!process.env.UV_THREADPOOL_SIZE) {
  process.env.UV_THREADPOOL_SIZE = config.system.threadPoolSize.toString();
}

// 设置环境变量
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

// 设置日志级别环境变量
if (config.logging.level) {
  process.env.LOG_LEVEL = config.logging.level.toLowerCase();
}

// 在设置环境变量后导入logger和服务器
const { defaultLogger } = require('./utils/logger');
const logger = defaultLogger.child('Start');
const PixivServer = require('./server');

// 如果配置了代理，设置环境变量
if (config.proxy.enabled === true || (config.proxy.enabled === "auto" && config.proxy.port)) {
  // 显式配置代理端口
  if (config.proxy.port) {
    process.env.PROXY_PORT = config.proxy.port.toString();
    logger.info(`代理端口已设置为: ${config.proxy.port}`);
  }
} else if (config.proxy.enabled === "auto") {
  // 自动检测系统代理
  let systemProxy = process.env.HTTP_PROXY || process.env.HTTPS_PROXY || process.env.http_proxy || process.env.https_proxy;
  
  // 如果环境变量没有设置，尝试从Windows注册表获取
  if (!systemProxy && os.platform() === 'win32') {
    const winProxy = getWindowsProxy();
    if (winProxy) {
      systemProxy = winProxy;
      logger.info(`通过注册表检测到系统代理: ${systemProxy}`);
    }
  }

  if (systemProxy) {
    logger.info(`检测到系统代理: ${systemProxy}`);
    // 从系统代理URL中提取端口
    // 支持格式:
    // 1. http://127.0.0.1:7890
    // 2. 127.0.0.1:7890
    // 3. localhost:7890
    const match = systemProxy.match(/(?:127\.0\.0\.1|localhost):(\d+)/);
    if (match) {
      process.env.PROXY_PORT = match[1];
      
      // 确保HTTP_PROXY环境变量被设置，供axios/proxy-agent使用
      let proxyUrl = systemProxy;
      if (!proxyUrl.startsWith('http://') && !proxyUrl.startsWith('https://')) {
        proxyUrl = `http://${proxyUrl}`;
      }

      if (!process.env.HTTP_PROXY) {
        process.env.HTTP_PROXY = proxyUrl;
        logger.info(`已设置 HTTP_PROXY 环境变量: ${proxyUrl}`);
      }
      if (!process.env.HTTPS_PROXY) {
        process.env.HTTPS_PROXY = proxyUrl;
        logger.info(`已设置 HTTPS_PROXY 环境变量: ${proxyUrl}`);
      }
      
      logger.info(`自动设置代理端口为: ${match[1]}`);
    } else {
      logger.warn(`无法从代理字符串中解析端口: ${systemProxy}`);
    }
  } else {
    logger.info('未检测到系统代理，将尝试使用系统代理环境变量');
  }
}

// 设置服务器端口
if (config.server.port) {
  process.env.PORT = config.server.port.toString();
  logger.info(`服务器端口已设置为: ${config.server.port}`);
}

// 输出日志级别信息
logger.info(`日志级别: ${config.logging.level}`);

// 设置自动打开浏览器选项
if (config.server.autoOpenBrowser !== undefined) {
  process.env.AUTO_OPEN_BROWSER = config.server.autoOpenBrowser.toString();
  logger.info(`自动打开浏览器: ${config.server.autoOpenBrowser ? '启用' : '禁用'}`);
}

logger.info('启动 Pixiv 后端服务器...');
// logger.info('配置信息:', {
//   serverPort: config.server.port,
//   proxyMode: config.proxy.enabled,
//   proxyPort: config.proxy.enabled === true && config.proxy.port ? config.proxy.port : 
//             (config.proxy.enabled === "auto" ? '自动检测' : '未启用'),
//   logLevel: config.logging.level,
//   autoOpenBrowser: config.server.autoOpenBrowser,
//   threadPoolSize: config.system.threadPoolSize
// });

// 创建服务器实例
const server = new PixivServer();

// 处理进程信号
process.on('SIGINT', async () => {
  logger.info('收到 SIGINT 信号，正在关闭服务器...');
  await server.shutdown();
});

process.on('SIGTERM', async () => {
  logger.info('收到 SIGTERM 信号，正在关闭服务器...');
  await server.shutdown();
});

// 处理未捕获的异常
process.on('uncaughtException', error => {
  logger.error('未捕获的异常', error);
  logger.error('异常堆栈:', error.stack);
  process.exit(1);
});

process.on('unhandledRejection', (reason, promise) => {
  logger.error('未处理的 Promise 拒绝');
  logger.error('拒绝原因:', reason);
  if (reason instanceof Error) {
    logger.error('错误堆栈:', reason.stack);
  }
  logger.error('Promise:', promise);
  
  // 不要立即退出进程，而是记录错误并继续运行
  // 这样可以避免因为自动恢复任务的小错误而停止整个服务
  logger.warn('继续运行服务器，但建议检查上述错误');
});

// 启动服务器
server
  .init()
  .then(() => server.start())
  .catch(error => {
    logger.error('服务器启动失败', error);
    process.exit(1);
  });
