#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
VWED任务系统集成启动器
先显示配置界面，配置完成后直接启动服务
支持后台运行模式
"""

import sys
import os
import threading
import time
import logging
import argparse
from pathlib import Path

# 添加项目根目录到Python路径
if getattr(sys, 'frozen', False):
    # 打包后的环境
    project_root = Path(sys.executable).parent
else:
    # 开发环境
    project_root = Path(__file__).parent.parent

sys.path.insert(0, str(project_root))

# 导入配置相关模块
try:
    from config_tool.startup_loader import load_startup_config, ensure_config_exists
except ImportError:
    print("警告: 无法导入配置加载器")

class IntegratedLauncher:
    """集成启动器"""
    
    def __init__(self, headless=False):
        self.app = None
        self.service_started = False
        self.config_completed = False
        self.headless = headless
        
        # 在无窗口模式下重定向标准流
        if self.headless:
            self._setup_headless_mode()
        
        self.setup_logging()
    
    def _setup_headless_mode(self):
        """设置无窗口模式的标准流重定向"""
        try:
            # 创建空的文件对象来代替标准流
            import io
            null_file = io.StringIO()
            
            # 重定向标准流到空文件，避免None对象引起的问题
            if sys.stdout is None:
                sys.stdout = null_file
            if sys.stderr is None:
                sys.stderr = null_file
            if sys.stdin is None:
                sys.stdin = io.StringIO("")
                
        except Exception as e:
            # 如果重定向失败，记录错误但不中断程序
            pass
        
    def setup_logging(self):
        """设置日志记录"""
        log_file = Path("vwed_service.log")
        
        # 配置日志格式
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        )
        
        # 文件日志处理器
        file_handler = logging.FileHandler(log_file, encoding='utf-8')
        file_handler.setLevel(logging.INFO)
        file_handler.setFormatter(formatter)
        
        # 获取根日志器
        self.logger = logging.getLogger('IntegratedLauncher')
        self.logger.setLevel(logging.INFO)
        self.logger.addHandler(file_handler)
        
        # 如果不是无头模式，也添加控制台日志
        if not self.headless:
            console_handler = logging.StreamHandler()
            console_handler.setLevel(logging.INFO)
            console_handler.setFormatter(formatter)
            self.logger.addHandler(console_handler)
    
    def log_and_print(self, message, level=logging.INFO):
        """记录日志并在非无头模式下打印"""
        self.logger.log(level, message)
        if not self.headless:
            print(message)
        
    def show_startup_message(self):
        """显示启动信息"""
        self.log_and_print("=" * 60)
        self.log_and_print("              VWED任务系统启动器")
        self.log_and_print("=" * 60)
        self.log_and_print("正在初始化系统...")
        
        # 确保配置文件存在
        try:
            ensure_config_exists()
            load_startup_config()
        except Exception as e:
            self.log_and_print(f"配置初始化失败: {e}", logging.ERROR)
    
    def start_configuration_gui(self):
        """启动配置GUI"""
        # 检查是否存在配置文件且配置是否完整
        config_file = Path("config.ini")
        if config_file.exists() and self.check_config_complete():
            self.log_and_print("检测到完整的配置文件，跳过配置界面直接启动服务...")
            self.log_and_print("如需重新配置，请删除config.ini文件后重新启动")
            
            # 模拟配置完成，直接启动服务
            self.on_config_completed({})
            return
        
        # 无头模式下跳过GUI
        if self.headless:
            self.log_and_print("无头模式运行，使用默认配置启动服务...")
            self.start_service()
            return
        
        try:
            from config_tool.integrated_config_gui import IntegratedConfigGUI
            
            self.log_and_print("启动配置界面...")
            self.config_gui = IntegratedConfigGUI(self.on_config_completed)
            self.config_gui.run()
            
        except ImportError as e:
            self.log_and_print(f"无法导入配置界面: {e}", logging.ERROR)
            # 如果GUI不可用，使用默认配置直接启动服务
            self.log_and_print("使用默认配置启动服务...")
            self.start_service()
        except Exception as e:
            self.log_and_print(f"配置界面启动失败: {e}", logging.ERROR)
            self.start_service()
    
    def check_config_complete(self):
        """检查配置是否完整"""
        try:
            import configparser
            config = configparser.ConfigParser()
            config.read("config.ini", encoding='utf-8')
            
            # 检查必要的配置项
            required_sections = {
                'database': ['username', 'password', 'host'],
                'api': ['tf_api_base_url']
            }
            
            for section, keys in required_sections.items():
                if section not in config:
                    return False
                for key in keys:
                    if key not in config[section] or not config[section][key].strip():
                        return False
            
            return True
        except Exception as e:
            self.log_and_print(f"检查配置文件失败: {e}", logging.ERROR)
            return False
    
    def on_config_completed(self, config_data):
        """配置完成回调"""
        self.log_and_print("配置完成，准备启动服务...")
        self.config_completed = True
        
        # 应用配置到环境变量
        if 'database' in config_data:
            os.environ.update({
                'DB_USER': config_data['database'].get('username', 'root'),
                'DB_PASSWORD': config_data['database'].get('password', 'root'),
                'DB_HOST': config_data['database'].get('host', 'localhost')
            })
        
        if 'api' in config_data:
            os.environ['TF_API_BASE_URL'] = config_data['api'].get('tf_api_base_url', 'http://111.231.146.230:4080/jeecg-boot')
        
        self.log_and_print("环境变量已设置，启动服务...")
        
        # 直接启动服务，不使用守护线程
        self.start_service()
    
    def start_service(self):
        """启动VWED服务"""
        if self.service_started:
            self.log_and_print("服务已经在运行中...")
            return
        
        try:
            self.log_and_print("\n" + "=" * 60)
            self.log_and_print("              启动VWED任务系统服务")
            self.log_and_print("=" * 60)
            
            # 写入PID文件用于后台管理
            pid_file = Path("vwed_service.pid")
            with open(pid_file, 'w') as f:
                f.write(str(os.getpid()))
            
            try:
                # 导入主程序
                from app import app, settings
                from utils.logger import get_logger
                
                logger = get_logger("launcher")
                
                # 标记服务已启动
                self.service_started = True
                
                port = 8000
                self.log_and_print(f"服务启动成功！")
                self.log_and_print(f"请在浏览器中访问: http://localhost:{port}")
                self.log_and_print(f"API文档地址: http://localhost:{port}/docs")
                if not self.headless:
                    self.log_and_print("\n按 Ctrl+C 停止服务")
                
                # 启动服务器
                import uvicorn
                
                # 在无窗口模式下使用简化配置
                if self.headless:
                    # 无窗口模式：禁用reload、单worker、简化日志
                    uvicorn.run(
                        app,  # 直接传递app对象而不是字符串
                        host="0.0.0.0",
                        port=port,
                        reload=False,
                        workers=1,
                        access_log=False,  # 禁用访问日志避免格式化问题
                        log_config=None   # 禁用默认日志配置
                    )
                else:
                    # 前台模式：使用正常配置
                    uvicorn.run(
                        "app:app",
                        host="0.0.0.0",
                        port=port,
                        reload=settings.SERVER_RELOAD,
                        workers=settings.SERVER_WORKERS
                    )
                    
            except Exception as uvicorn_error:
                self.log_and_print(f"Uvicorn启动失败: {uvicorn_error}", logging.ERROR)
                
                # 尝试使用最基本的方式启动
                self.log_and_print("尝试使用基本模式启动服务...", logging.WARNING)
                try:
                    from app import app
                    import uvicorn
                    uvicorn.run(
                        app,
                        host="0.0.0.0", 
                        port=8000,
                        log_level="error"  # 只显示错误日志
                    )
                except Exception as fallback_error:
                    self.log_and_print(f"基本模式启动也失败: {fallback_error}", logging.ERROR)
                    raise fallback_error
            
        except ImportError as e:
            self.log_and_print(f"无法导入主程序模块: {e}", logging.ERROR)
            self.log_and_print("请检查项目依赖是否正确安装", logging.ERROR)
        except Exception as e:
            self.log_and_print(f"服务启动失败: {e}", logging.ERROR)
            import traceback
            self.log_and_print(traceback.format_exc(), logging.ERROR)
        finally:
            self.service_started = False
            # 清理PID文件
            pid_file = Path("vwed_service.pid")
            if pid_file.exists():
                pid_file.unlink()
    
    def cleanup(self):
        """清理资源"""
        try:
            self.log_and_print("清理资源中...")
            if hasattr(self, 'config_gui'):
                if hasattr(self.config_gui, 'root') and self.config_gui.root:
                    self.config_gui.root.destroy()
            
            # 清理PID文件
            pid_file = Path("vwed_service.pid")
            if pid_file.exists():
                pid_file.unlink()
        except:
            pass

def main():
    """主函数"""
    # 解析命令行参数
    parser = argparse.ArgumentParser(description='VWED任务系统集成启动器')
    parser.add_argument('--headless', action='store_true', 
                       help='无头模式运行（后台运行，不显示GUI）')
    parser.add_argument('--daemon', action='store_true',
                       help='守护进程模式运行')
    
    args = parser.parse_args()
    
    launcher = None
    try:
        launcher = IntegratedLauncher(headless=args.headless)
        
        # 显示启动信息
        launcher.show_startup_message()
        
        # 启动配置GUI
        launcher.start_configuration_gui()
        
    except KeyboardInterrupt:
        if launcher:
            launcher.log_and_print("\n程序被用户中断")
        else:
            print("\n程序被用户中断")
    except Exception as e:
        if launcher:
            launcher.log_and_print(f"程序异常退出: {e}", logging.ERROR)
            import traceback
            launcher.log_and_print(traceback.format_exc(), logging.ERROR)
        else:
            print(f"程序异常退出: {e}")
            import traceback
            traceback.print_exc()
            
        if not args.headless:
            input("按回车键退出...")
    finally:
        # 清理资源
        if launcher:
            launcher.cleanup()

def cleanup_and_exit():
    """清理资源并退出"""
    print("正在清理资源...")
    # 强制退出所有线程
    os._exit(0)

if __name__ == "__main__":
    try:
        main()
    except:
        cleanup_and_exit()