#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
同步脚本 — 将本地 SQLite 中的用例同步到服务器 MySQL

用法:
    python scripts/sync_to_server.py [--case-id CASE_ID] [--all] [--last-days N]

说明:
    默认只同步最近 1 天新增的用例。
    --all 同步所有用例
    --case-id CASE_ID 同步指定用例
    --last-days N 同步最近 N 天的用例

作者：czj
创建日期：2026-07-29
"""

import argparse
import json
import logging
import os
import sys
from datetime import datetime, timedelta
from pathlib import Path

# 添加项目根目录到路径
sys.path.insert(0, str(Path(__file__).parent.parent))

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)

# 服务器 API 地址
SERVER_URL = "http://192.168.5.60/api/cases"


def get_local_cases(case_id: str = None, all_cases: bool = False, last_days: int = 1) -> list:
    """
    从本地 SQLite 获取用例

    Args:
        case_id: 指定用例 ID
        all_cases: 是否同步所有用例
        last_days: 同步最近 N 天的用例

    Returns:
        list: 用例列表
    """
    try:
        import asyncio
        from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
        from sqlalchemy import select
        from sqlalchemy.orm import sessionmaker

        from app.config import settings
        from app.models.test_case import TestCase

        async def _fetch():
            engine = create_async_engine(settings.DATABASE_URL)
            async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

            async with async_session() as session:
                query = select(TestCase)

                if case_id:
                    query = query.where(TestCase.id == case_id)
                elif not all_cases:
                    # 默认只同步最近 N 天的用例
                    since = datetime.utcnow() - timedelta(days=last_days)
                    query = query.where(TestCase.created_at >= since)

                query = query.order_by(TestCase.created_at.desc())
                result = await session.execute(query)
                cases = result.scalars().all()

                case_list = []
                for c in cases:
                    case_list.append({
                        "id": c.id,
                        "module_id": c.module_id,
                        "name": c.name,
                        "description": c.description or "",
                        "status": c.status or "active",
                        "priority": c.priority or "medium",
                        "tags": c.tags or [],
                        "steps": c.steps or [],
                        "config": c.config or {},
                        "case_type": c.case_type or "ui",
                        "created_at": c.created_at.isoformat() if c.created_at else None,
                    })

                return case_list

        return asyncio.run(_fetch())

    except Exception as e:
        logger.error(f"读取本地数据库失败: {e}")
        logger.error("请确保在项目根目录运行此脚本，且本地数据库 data/test_platform.db 存在")
        return []


def sync_to_server(cases: list) -> dict:
    """
    通过 API 将用例同步到服务器

    Args:
        cases: 用例列表

    Returns:
        dict: 同步结果统计
    """
    import requests

    success = 0
    failed = 0
    errors = []

    for case in cases:
        try:
            # 构建请求体（与 TestCaseCreate Schema 一致）
            payload = {
                "module_id": case["module_id"],
                "name": case["name"],
                "description": case["description"],
                "status": case["status"],
                "priority": case["priority"],
                "tags": case["tags"],
                "steps": case["steps"],
                "config": case.get("config", {}),
                "case_type": case.get("case_type", "ui"),
            }

            resp = requests.post(SERVER_URL, json=payload, timeout=30)

            if resp.status_code == 201:
                success += 1
                logger.info(f"  ✅ {case['name']} ({case['id']})")
            else:
                failed += 1
                err_msg = f"{case['name']}: HTTP {resp.status_code} - {resp.text[:200]}"
                errors.append(err_msg)
                logger.warning(f"  ❌ {err_msg}")

        except Exception as e:
            failed += 1
            err_msg = f"{case['name']}: {str(e)}"
            errors.append(err_msg)
            logger.error(f"  ❌ {err_msg}")

    return {
        "success_count": success,
        "failed_count": failed,
        "errors": errors,
    }


def main():
    parser = argparse.ArgumentParser(description="同步本地用例到服务器")
    parser.add_argument("--case-id", help="同步指定用例")
    parser.add_argument("--all", action="store_true", help="同步所有用例")
    parser.add_argument("--last-days", type=int, default=1, help="同步最近 N 天的用例（默认 1 天）")
    args = parser.parse_args()

    logger.info("=" * 50)
    logger.info("开始同步用例到服务器...")
    logger.info(f"服务器地址: {SERVER_URL}")

    # 获取本地用例
    cases = get_local_cases(
        case_id=args.case_id,
        all_cases=args.all,
        last_days=args.last_days,
    )

    if not cases:
        logger.warning("没有找到需要同步的用例")
        return

    logger.info(f"找到 {len(cases)} 个待同步用例")

    # 同步到服务器
    result = sync_to_server(cases)

    logger.info("=" * 50)
    logger.info(f"同步完成: 成功 {result['success_count']}，失败 {result['failed_count']}")

    if result["errors"]:
        logger.warning("失败详情:")
        for err in result["errors"][:10]:
            logger.warning(f"  - {err}")
        if len(result["errors"]) > 10:
            logger.warning(f"  ... 还有 {len(result['errors']) - 10} 个错误")

    logger.info("=" * 50)


if __name__ == "__main__":
    main()