#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
YG_FT_Base 统一启动脚本
同时启动后端 API 服务和 Web 静态服务器

使用方法:
    python start_all.py start    # 启动所有服务
    python start_all.py stop     # 停止所有服务
    python start_all.py restart  # 重启所有服务
    python start_all.py status   # 查看服务状态
"""
import os
import sys
import yaml
import signal
import subprocess
import time
from pathlib import Path

# 获取脚本所在目录
SCRIPT_DIR = Path(__file__).parent.absolute()
CONFIG_FILE = SCRIPT_DIR / "config.yaml"
WEB_DIR = SCRIPT_DIR / "web"

# PID 文件路径
API_PID_FILE = SCRIPT_DIR / ".api.pid"
WEB_PID_FILE = SCRIPT_DIR / ".web.pid"


def load_config():
    """加载配置文件"""
    if not CONFIG_FILE.exists():
        print(f"❌ 配置文件不存在: {CONFIG_FILE}")
        sys.exit(1)

    with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
        config = yaml.safe_load(f)

    app_config = config.get('app', {})
    return {
        'api_port': app_config.get('port', 7861),
        'web_port': app_config.get('web_port', 7862)
    }


def is_port_in_use(port):
    """检查端口是否被占用"""
    import socket
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        return s.connect_ex(('localhost', port)) == 0


def get_pid(pid_file):
    """获取 PID"""
    if pid_file.exists():
        try:
            return int(pid_file.read_text().strip())
        except:
            return None
    return None


def is_process_running(pid):
    """检查进程是否在运行"""
    try:
        os.kill(pid, 0)
        return True
    except OSError:
        return False


def kill_process(pid_file):
    """杀死进程"""
    pid = get_pid(pid_file)
    if pid and is_process_running(pid):
        try:
            os.kill(pid, signal.SIGTERM)
            time.sleep(0.5)
            # 如果还在运行，强制杀死
            if is_process_running(pid):
                os.kill(pid, signal.SIGKILL)
            return True
        except OSError:
            pass
    pid_file.unlink(missing_ok=True)
    return False


def check_virtual_env():
    """检查虚拟环境是否存在"""
    venv_path = SCRIPT_DIR / "B_venv"
    if not venv_path.exists():
        print("⚠️  虚拟环境不存在，请先运行 create_venv.sh 创建")
        return False
    return True


def start_api():
    """启动后端 API 服务"""
    config = load_config()
    api_port = config['api_port']

    print("🚀 启动后端 API 服务...")

    if not check_virtual_env():
        return False

    if is_port_in_use(api_port):
        print(f"❌ 端口 {api_port} 已被占用，后端服务可能已在运行")
        return False

    venv_python = SCRIPT_DIR / "B_venv" / "bin" / "python"
    main_py = SCRIPT_DIR / "src" / "main.py"

    if not venv_python.exists():
        venv_python = SCRIPT_DIR / "B_venv" / "Scripts" / "python.exe"  # Windows

    if not main_py.exists():
        print(f"❌ 找不到主程序文件: {main_py}")
        return False

    # 启动进程
    env = os.environ.copy()
    env['PYTHONUNBUFFERED'] = '1'

    proc = subprocess.Popen(
        [str(venv_python), str(main_py)],
        cwd=str(SCRIPT_DIR),
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        text=True,
        bufsize=1,
        env=env
    )

    # 写入 PID
    with open(API_PID_FILE, 'w') as f:
        f.write(str(proc.pid))

    # 等待服务启动
    time.sleep(2)

    if proc.poll() is not None:
        print("❌ 后端服务启动失败")
        API_PID_FILE.unlink(missing_ok=True)
        return False

    print(f"✅ 后端服务已启动 (PID: {proc.pid}, 端口: {api_port})")
    return True


def start_web():
    """启动 Web 静态服务器"""
    config = load_config()
    web_port = config['web_port']

    print("🚀 启动 Web 静态服务器...")

    # 从项目根目录启动，这样 /lib/... 路径可以正确映射到 $PROJECT/lib/...
    web_root = SCRIPT_DIR

    if not web_root.exists():
        print(f"❌ Web 目录不存在: {web_root}")
        return False

    if is_port_in_use(web_port):
        print(f"⚠️  端口 {web_port} 已被占用，Web 服务可能已在运行")
        return False

    # 使用 python 启动简单 HTTP 服务器（从项目根目录）
    env = os.environ.copy()
    env['PYTHONUNBUFFERED'] = '1'

    proc = subprocess.Popen(
        [sys.executable, '-m', 'http.server', str(web_port)],
        cwd=str(web_root),
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        text=True,
        bufsize=1,
        env=env
    )

    # 写入 PID
    with open(WEB_PID_FILE, 'w') as f:
        f.write(str(proc.pid))

    time.sleep(1)

    if proc.poll() is not None:
        print("❌ Web 服务启动失败")
        WEB_PID_FILE.unlink(missing_ok=True)
        return False

    print(f"✅ Web 服务已启动 (PID: {proc.pid}, 端口: {web_port})")
    return True


def stop_all():
    """停止所有服务"""
    print("🛑 停止所有服务...")

    # 停止后端服务
    if kill_process(API_PID_FILE):
        print("✅ 后端服务已停止")

    # 停止 Web 服务
    if kill_process(WEB_PID_FILE):
        print("✅ Web 服务已停止")

    # 清理残留进程
    subprocess.run(['pkill', '-f', 'src/main.py'], capture_output=True)
    config = load_config()
    subprocess.run(['pkill', '-f', f'http.server {config["web_port"]}'], capture_output=True)


def show_status():
    """显示服务状态"""
    config = load_config()
    api_port = config['api_port']
    web_port = config['web_port']

    print("\n📊 服务状态:")
    print("-" * 40)

    api_pid = get_pid(API_PID_FILE)
    if api_pid and is_process_running(api_pid):
        print(f"✅ 后端 API: 运行中 (PID: {api_pid}, 端口: {api_port})")
    else:
        print(f"❌ 后端 API: 未运行 (端口: {api_port})")

    web_pid = get_pid(WEB_PID_FILE)
    if web_pid and is_process_running(web_pid):
        print(f"✅ Web 服务: 运行中 (PID: {web_pid}, 端口: {web_port})")
    else:
        print(f"❌ Web 服务: 未运行 (端口: {web_port})")

    print("-" * 40)
    print("\n🌐 访问地址:")
    print(f"   - 后端 API: http://localhost:{api_port}")
    print(f"   - Web 页面: http://localhost:{web_port}/web/pages/main.html")
    print()


def main():
    if len(sys.argv) < 2:
        print("用法: python start_all.py {start|stop|restart|status}")
        print()
        print("命令:")
        print("   start   - 启动所有服务")
        print("   stop    - 停止所有服务")
        print("   restart - 重启所有服务")
        print("   status  - 查看服务状态")
        sys.exit(1)

    command = sys.argv[1].lower()

    print("====================================")
    print("YG_FT_Base 统一启动脚本 (Python版)")
    print("====================================")
    print()

    config = load_config()
    print(f"📦 端口配置:")
    print(f"   - 后端 API: {config['api_port']}")
    print(f"   - Web 服务: {config['web_port']}")
    print()

    if command == 'start':
        start_api()
        start_web()
        print()
        print("====================================")
        print("所有服务已启动！")
        print("====================================")
        show_status()

    elif command == 'stop':
        stop_all()
        print("✅ 所有服务已停止")

    elif command == 'restart':
        stop_all()
        time.sleep(1)
        start_api()
        start_web()
        print()
        print("====================================")
        print("所有服务已重启！")
        print("====================================")
        show_status()

    elif command == 'status':
        show_status()

    else:
        print(f"❌ 未知命令: {command}")
        print("用法: python start_all.py {start|stop|restart|status}")
        sys.exit(1)


if __name__ == '__main__':
    main()
