#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称：migration_add_dependencies.py
模块描述：数据库迁移脚本 - 添加依赖管理相关表和字段

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

import asyncio
import logging
import sys
import os
from pathlib import Path

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

from sqlalchemy import text
from app.database import engine, Base
from app.models.test_case import TestCase
from app.models.case_dependency import CaseDependency
from app.models.case_result import CaseResult
from app.models.execution import Execution

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


async def migrate():
    """
    执行数据库迁移

    添加依赖管理相关的表和字段
    """
    logger.info("开始数据库迁移...")

    try:
        # 创建所有新表
        async with engine.begin() as conn:
            # 创建 case_dependencies 表
            logger.info("创建 case_dependencies 表...")
            await conn.execute(text("""
                CREATE TABLE IF NOT EXISTS case_dependencies (
                    id TEXT PRIMARY KEY,
                    case_id TEXT NOT NULL,
                    depends_on_case_id TEXT NOT NULL,
                    dependency_type TEXT DEFAULT 'hard',
                    "order" INTEGER DEFAULT 0,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    FOREIGN KEY (case_id) REFERENCES test_cases(id) ON DELETE CASCADE,
                    FOREIGN KEY (depends_on_case_id) REFERENCES test_cases(id) ON DELETE CASCADE
                )
            """))

            # 为 case_dependencies 表创建索引
            logger.info("创建索引...")
            await conn.execute(text("""
                CREATE INDEX IF NOT EXISTS ix_case_dependencies_case_id
                ON case_dependencies(case_id)
            """))
            await conn.execute(text("""
                CREATE INDEX IF NOT EXISTS ix_case_dependencies_depends_on_case_id
                ON case_dependencies(depends_on_case_id)
            """))

            # 为 test_cases 表添加新字段
            logger.info("扩展 test_cases 表...")
            try:
                await conn.execute(text("""
                    ALTER TABLE test_cases ADD COLUMN depends_on JSON DEFAULT '[]'
                """))
            except Exception as e:
                if "duplicate column" not in str(e).lower():
                    logger.warning(f"添加 depends_on 字段失败: {str(e)}")

            try:
                await conn.execute(text("""
                    ALTER TABLE test_cases ADD COLUMN parameters JSON DEFAULT '{}'
                """))
            except Exception as e:
                if "duplicate column" not in str(e).lower():
                    logger.warning(f"添加 parameters 字段失败: {str(e)}")

            try:
                await conn.execute(text("""
                    ALTER TABLE test_cases ADD COLUMN condition JSON DEFAULT '{}'
                """))
            except Exception as e:
                if "duplicate column" not in str(e).lower():
                    logger.warning(f"添加 condition 字段失败: {str(e)}")

            try:
                await conn.execute(text("""
                    ALTER TABLE test_cases ADD COLUMN "order" INTEGER DEFAULT 0
                """))
            except Exception as e:
                if "duplicate column" not in str(e).lower():
                    logger.warning(f"添加 order 字段失败: {str(e)}")

            try:
                await conn.execute(text("""
                    ALTER TABLE test_cases ADD COLUMN version INTEGER DEFAULT 1
                """))
            except Exception as e:
                if "duplicate column" not in str(e).lower():
                    logger.warning(f"添加 version 字段失败: {str(e)}")

            # 为 executions 表添加新字段
            logger.info("扩展 executions 表...")
            try:
                await conn.execute(text("""
                    ALTER TABLE executions ADD COLUMN execution_mode TEXT DEFAULT 'sequential'
                """))
            except Exception as e:
                if "duplicate column" not in str(e).lower():
                    logger.warning(f"添加 execution_mode 字段失败: {str(e)}")

            try:
                await conn.execute(text("""
                    ALTER TABLE executions ADD COLUMN max_parallel INTEGER DEFAULT 1
                """))
            except Exception as e:
                if "duplicate column" not in str(e).lower():
                    logger.warning(f"添加 max_parallel 字段失败: {str(e)}")

            try:
                await conn.execute(text("""
                    ALTER TABLE executions ADD COLUMN param_values JSON DEFAULT '{}'
                """))
            except Exception as e:
                if "duplicate column" not in str(e).lower():
                    logger.warning(f"添加 param_values 字段失败: {str(e)}")

            # 为 case_results 表添加新字段
            logger.info("扩展 case_results 表...")
            try:
                await conn.execute(text("""
                    ALTER TABLE case_results ADD COLUMN param_instance JSON DEFAULT '{}'
                """))
            except Exception as e:
                if "duplicate column" not in str(e).lower():
                    logger.warning(f"添加 param_instance 字段失败: {str(e)}")

            try:
                await conn.execute(text("""
                    ALTER TABLE case_results ADD COLUMN dependency_status TEXT DEFAULT 'ok'
                """))
            except Exception as e:
                if "duplicate column" not in str(e).lower():
                    logger.warning(f"添加 dependency_status 字段失败: {str(e)}")

            try:
                await conn.execute(text("""
                    ALTER TABLE case_results ADD COLUMN condition_met BOOLEAN DEFAULT 1
                """))
            except Exception as e:
                if "duplicate column" not in str(e).lower():
                    logger.warning(f"添加 condition_met 字段失败: {str(e)}")

        logger.info("✅ 数据库迁移完成！")

    except Exception as e:
        logger.error(f"❌ 数据库迁移失败: {str(e)}")
        raise


async def rollback():
    """
    回滚数据库迁移

    删除添加的表和字段
    """
    logger.info("开始回滚数据库迁移...")

    try:
        async with engine.begin() as conn:
            # 删除 case_dependencies 表
            logger.info("删除 case_dependencies 表...")
            await conn.execute(text("""
                DROP TABLE IF EXISTS case_dependencies
            """))

            # 注意：SQLite 不支持 DROP COLUMN，所以字段会保留
            # 如需完全回滚，需要重新创建表

        logger.info("✅ 回滚完成！")

    except Exception as e:
        logger.error(f"❌ 回滚失败: {str(e)}")
        raise


if __name__ == "__main__":
    import sys

    if len(sys.argv) > 1 and sys.argv[1] == "rollback":
        asyncio.run(rollback())
    else:
        asyncio.run(migrate())