#!/usr/bin/env python3
"""
项目验证脚本

用于验证项目结构和资产的完整性。
"""

import sys
import json
from typing import Dict, List, Any


class ProjectValidator:
    """项目验证器"""
    
    VALID_PROJECT_TYPES = ["video"]
    VALID_STYLES = ["anime", "realistic", "cinematic", "cartoon"]
    VALID_ASSET_TYPES = ["character", "scene", "prop"]
    
    def __init__(self):
        self.errors = []
        self.warnings = []
        self.suggestions = []
    
    def validate_project(self, project: Dict[str, Any]) -> Dict[str, Any]:
        """验证项目配置"""
        self.errors = []
        self.warnings = []
        self.suggestions = []
        
        # 检查必需字段
        required_fields = ["name", "type", "style"]
        for field in required_fields:
            if field not in project:
                self.errors.append(f"缺少必需字段: {field}")
        
        # 检查项目名称
        if "name" in project:
            name = project["name"]
            if not name or len(name) == 0:
                self.errors.append("项目名称不能为空")
            elif len(name) > 100:
                self.errors.append("项目名称过长（超过 100 字符）")
        
        # 检查项目类型
        if "type" in project:
            if project["type"] not in self.VALID_PROJECT_TYPES:
                self.errors.append(
                    f"无效的项目类型: {project['type']}，"
                    f"有效值: {', '.join(self.VALID_PROJECT_TYPES)}"
                )
        
        # 检查风格
        if "style" in project:
            if project["style"] not in self.VALID_STYLES:
                self.errors.append(
                    f"无效的风格: {project['style']}，"
                    f"有效值: {', '.join(self.VALID_STYLES)}"
                )
        
        # 检查描述
        if "description" in project:
            desc = project["description"]
            if len(desc) > 1000:
                self.warnings.append("项目描述过长（超过 1000 字符）")
        else:
            self.suggestions.append("建议添加项目描述")
        
        # 检查资产
        if "assets" in project:
            self._validate_assets(project["assets"])
        else:
            self.warnings.append("项目没有资产")
        
        return self._build_result()
    
    def validate_asset(self, asset: Dict[str, Any]) -> Dict[str, Any]:
        """验证单个资产"""
        self.errors = []
        self.warnings = []
        self.suggestions = []
        
        # 检查必需字段
        required_fields = ["name", "type", "description"]
        for field in required_fields:
            if field not in asset:
                self.errors.append(f"缺少必需字段: {field}")
        
        # 检查资产类型
        if "type" in asset:
            if asset["type"] not in self.VALID_ASSET_TYPES:
                self.errors.append(
                    f"无效的资产类型: {asset['type']}，"
                    f"有效值: {', '.join(self.VALID_ASSET_TYPES)}"
                )
        
        # 检查名称
        if "name" in asset:
            if not asset["name"] or len(asset["name"]) == 0:
                self.errors.append("资产名称不能为空")
        
        # 检查描述
        if "description" in asset:
            desc = asset["description"]
            if len(desc) < 10:
                self.warnings.append("资产描述过短，建议添加更多细节")
            elif len(desc) > 500:
                self.warnings.append("资产描述过长")
        
        # 根据类型检查特定字段
        if "type" in asset:
            if asset["type"] == "character":
                self._validate_character(asset)
            elif asset["type"] == "scene":
                self._validate_scene(asset)
            elif asset["type"] == "prop":
                self._validate_prop(asset)
        
        return self._build_result()
    
    def _validate_assets(self, assets: List[Dict[str, Any]]):
        """验证资产列表"""
        if not assets or len(assets) == 0:
            self.warnings.append("资产列表为空")
            return
        
        # 统计资产类型
        type_counts = {}
        for asset in assets:
            asset_type = asset.get("type", "unknown")
            type_counts[asset_type] = type_counts.get(asset_type, 0) + 1
        
        # 检查资产平衡
        if "character" not in type_counts:
            self.warnings.append("项目没有角色资产")
        if "scene" not in type_counts:
            self.warnings.append("项目没有场景资产")
        
        # 检查每个资产
        for i, asset in enumerate(assets):
            result = self.validate_asset(asset)
            if not result["valid"]:
                self.errors.append(f"资产 {i+1} 验证失败: {result['errors']}")
    
    def _validate_character(self, character: Dict[str, Any]):
        """验证角色资产"""
        # 建议添加视觉特征
        if "visual_features" not in character:
            self.suggestions.append(
                f"角色 '{character.get('name', '未命名')}' 建议添加 visual_features 字段"
            )
        
        # 建议添加性格
        if "personality" not in character:
            self.suggestions.append(
                f"角色 '{character.get('name', '未命名')}' 建议添加 personality 字段"
            )
    
    def _validate_scene(self, scene: Dict[str, Any]):
        """验证场景资产"""
        # 建议添加氛围
        if "atmosphere" not in scene:
            self.suggestions.append(
                f"场景 '{scene.get('name', '未命名')}' 建议添加 atmosphere 字段"
            )
        
        # 建议添加时间
        if "time" not in scene:
            self.suggestions.append(
                f"场景 '{scene.get('name', '未命名')}' 建议添加 time 字段"
            )
    
    def _validate_prop(self, prop: Dict[str, Any]):
        """验证道具资产"""
        # 建议添加功能
        if "function" not in prop:
            self.suggestions.append(
                f"道具 '{prop.get('name', '未命名')}' 建议添加 function 字段"
            )
    
    def _build_result(self) -> Dict[str, Any]:
        """构建验证结果"""
        is_valid = len(self.errors) == 0
        
        return {
            "valid": is_valid,
            "errors": self.errors,
            "warnings": self.warnings,
            "suggestions": self.suggestions,
            "score": self._calculate_score()
        }
    
    def _calculate_score(self) -> int:
        """计算项目质量分数（0-100）"""
        score = 100
        score -= len(self.errors) * 30
        score -= len(self.warnings) * 10
        score -= len(self.suggestions) * 5
        return max(0, score)


def validate_project_file(file_path: str) -> Dict[str, Any]:
    """
    验证项目配置文件
    
    Args:
        file_path: 项目配置文件路径（JSON 格式）
    
    Returns:
        验证结果字典
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            project = json.load(f)
    except FileNotFoundError:
        return {
            "valid": False,
            "errors": [f"文件不存在: {file_path}"],
            "warnings": [],
            "suggestions": [],
            "score": 0
        }
    except json.JSONDecodeError as e:
        return {
            "valid": False,
            "errors": [f"JSON 解析错误: {str(e)}"],
            "warnings": [],
            "suggestions": [],
            "score": 0
        }
    
    validator = ProjectValidator()
    return validator.validate_project(project)


def print_result(result: Dict[str, Any]):
    """打印验证结果"""
    print("\n" + "="*60)
    print("项目验证结果")
    print("="*60)
    
    # 状态
    status = "✅ 通过" if result["valid"] else "❌ 未通过"
    print(f"\n状态: {status}")
    print(f"质量分数: {result['score']}/100")
    
    # 错误
    if result["errors"]:
        print(f"\n❌ 错误 ({len(result['errors'])}):")
        for i, error in enumerate(result["errors"], 1):
            print(f"  {i}. {error}")
    
    # 警告
    if result["warnings"]:
        print(f"\n⚠️  警告 ({len(result['warnings'])}):")
        for i, warning in enumerate(result["warnings"], 1):
            print(f"  {i}. {warning}")
    
    # 建议
    if result["suggestions"]:
        print(f"\n💡 建议 ({len(result['suggestions'])}):")
        for i, suggestion in enumerate(result["suggestions"], 1):
            print(f"  {i}. {suggestion}")
    
    print("\n" + "="*60 + "\n")


def main():
    """主函数"""
    if len(sys.argv) < 2:
        print("用法: python validate_project.py <project_file.json>")
        print("  project_file.json: 项目配置文件路径")
        sys.exit(1)
    
    file_path = sys.argv[1]
    
    print(f"\n验证项目文件: {file_path}")
    
    result = validate_project_file(file_path)
    print_result(result)
    
    # 返回状态码
    sys.exit(0 if result["valid"] else 1)


if __name__ == "__main__":
    main()
