#!/usr/bin/env python3
"""
分析原始输出格式脚本

这个脚本会读取capture_raw_outputs.py生成的JSON文件，
分析各个提供商的原始输出格式，为设计统一返回体提供参考。
"""

import json
import sys
from datetime import datetime
from pathlib import Path
from collections import defaultdict


def analyze_file(filepath):
    """分析单个JSON文件"""
    print(f"\n📄 分析文件: {filepath.name}")
    print("-" * 50)
    
    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            data = json.load(f)
        
        provider = data.get('provider', 'unknown')
        timestamp = data.get('timestamp', 'unknown')
        metadata = data.get('metadata', {})
        raw_data = data.get('raw_data', {})
        
        print(f"提供商: {provider}")
        print(f"时间戳: {timestamp}")
        print(f"元数据: {json.dumps(metadata, ensure_ascii=False, indent=2)}")
        
        # 分析原始数据结构
        print(f"\n📊 原始数据结构分析:")
        
        if isinstance(raw_data, dict):
            print(f"  类型: 字典 (dict)")
            print(f"  键数量: {len(raw_data)}")
            print(f"  所有键: {list(raw_data.keys())}")
            
            # 分析字典内容
            for key, value in raw_data.items():
                if isinstance(value, (list, dict)):
                    print(f"  - '{key}': {type(value).__name__}, 长度: {len(value)}")
                    if isinstance(value, list) and value:
                        sample = value[0] if len(value) > 0 else None
                        print(f"    示例元素类型: {type(sample).__name__}")
                        if isinstance(sample, dict) and sample:
                            print(f"    示例元素键: {list(sample.keys())[:5]}...")
                else:
                    print(f"  - '{key}': {type(value).__name__}, 值: {repr(str(value)[:50])}...")
        
        elif isinstance(raw_data, list):
            print(f"  类型: 列表 (list)")
            print(f"  元素数量: {len(raw_data)}")
            if raw_data:
                sample = raw_data[0]
                print(f"  示例元素类型: {type(sample).__name__}")
                if isinstance(sample, dict):
                    print(f"  示例元素键: {list(sample.keys())[:10]}")
                elif isinstance(sample, str):
                    print(f"  示例元素值: {sample[:50]}...")
        
        elif isinstance(raw_data, str):
            print(f"  类型: 字符串 (str)")
            print(f"  长度: {len(raw_data)} 字符")
            print(f"  前100字符: {raw_data[:100]}...")
        
        else:
            print(f"  类型: {type(raw_data).__name__}")
            print(f"  值: {repr(raw_data)}")
        
        return {
            'provider': provider,
            'type': type(raw_data).__name__,
            'structure': analyze_structure(raw_data),
            'sample': get_sample(raw_data)
        }
    
    except Exception as e:
        print(f"❌ 分析文件时出错: {e}")
        return None


def analyze_structure(data, depth=0, max_depth=3):
    """递归分析数据结构"""
    if depth > max_depth:
        return "..."  # 防止无限递归
    
    if isinstance(data, dict):
        result = {}
        for key, value in data.items():
            if isinstance(value, (dict, list)):
                result[key] = analyze_structure(value, depth + 1, max_depth)
            else:
                result[key] = type(value).__name__
        return result
    
    elif isinstance(data, list):
        if not data:
            return "空列表"
        
        # 检查列表元素是否一致
        elem_types = set(type(item).__name__ for item in data[:5])  # 只检查前5个
        if len(elem_types) == 1:
            elem_type = next(iter(elem_types))
            if elem_type == 'dict' and data[0]:
                # 分析字典结构
                sample = data[0]
                return {
                    'list_of': 'dict',
                    'keys': list(sample.keys()),
                    'count': len(data)
                }
            else:
                return {
                    'list_of': elem_type,
                    'count': len(data)
                }
        else:
            return {
                'list_of': 'mixed',
                'types': list(elem_types),
                'count': len(data)
            }
    
    else:
        return type(data).__name__


def get_sample(data, max_items=3):
    """获取数据样本"""
    if isinstance(data, dict):
        # 只取前几个键值对
        sample = {}
        for i, (key, value) in enumerate(data.items()):
            if i >= max_items:
                sample[f"...还有{len(data)-max_items}个键"] = "..."
                break
            if isinstance(value, (dict, list)):
                sample[key] = type(value).__name__
                if isinstance(value, dict) and value:
                    sample[key] += f" (keys: {list(value.keys())[:3]}...)"
                elif isinstance(value, list):
                    sample[key] += f" (length: {len(value)})"
            else:
                sample[key] = str(value)[:50] + ("..." if len(str(value)) > 50 else "")
        return sample
    
    elif isinstance(data, list):
        if not data:
            return []
        
        sample = []
        for i, item in enumerate(data[:max_items]):
            if isinstance(item, dict):
                sample.append({k: type(v).__name__ for k, v in list(item.items())[:3]})
            else:
                sample.append(str(item)[:50] + ("..." if len(str(item)) > 50 else ""))
        
        if len(data) > max_items:
            sample.append(f"...还有{len(data)-max_items}个元素")
        
        return sample
    
    else:
        return str(data)[:100] + ("..." if len(str(data)) > 100 else "")


def compare_providers(analyses):
    """比较不同提供商的数据格式"""
    print("\n" + "=" * 60)
    print("📈 提供商数据格式比较")
    print("=" * 60)
    
    # 按提供商类型分组
    by_type = defaultdict(list)
    for analysis in analyses:
        if analysis:
            by_type[analysis['type']].append(analysis['provider'])
    
    print("\n📋 按返回类型分组:")
    for data_type, providers in by_type.items():
        print(f"  {data_type}: {', '.join(providers)}")
    
    # 分析每个提供商的数据结构
    print("\n🔍 详细数据结构:")
    for analysis in analyses:
        if analysis:
            print(f"\n{analysis['provider']}:")
            print(f"  类型: {analysis['type']}")
            print(f"  结构: {json.dumps(analysis['structure'], ensure_ascii=False, indent=2)}")
            print(f"  样本: {json.dumps(analysis['sample'], ensure_ascii=False, indent=2)}")
    
    # 提出统一格式建议
    print("\n" + "=" * 60)
    print("💡 统一返回体格式建议")
    print("=" * 60)
    
    print("""
基于分析结果，建议的统一返回体格式：

{
  "success": boolean,           # 是否成功
  "provider": string,          # 提供商名称
  "timestamp": string,         # 时间戳
  "data": {                    # 实际数据
    "models": [               # 模型列表（统一为数组）
      {
        "id": string,         # 模型ID
        "name": string,       # 模型显示名称
        "provider": string,   # 提供商（可省略，默认为外层provider）
        "category": string,   # 分类（可选）
        "capabilities": [     # 能力列表（可选）
          "chat", "vision", "audio", etc.
        ],
        "context_length": int, # 上下文长度（可选）
        "description": string  # 描述（可选）
      }
    ],
    "categories": {           # 分类信息（可选）
      "category_name": [model_id1, model_id2, ...]
    }
  },
  "metadata": {               # 元数据
    "total_count": int,       # 总模型数
    "source": string,         # 数据来源（API/网页等）
    "raw_format": string      # 原始格式类型
  },
  "error": {                  # 错误信息（success为false时）
    "code": string,
    "message": string,
    "details": any
  }
}

需要进行的转换：
1. 智谱AI（dict of categories → 统一格式）
2. OpenRouter（list of model objects → 统一格式）
3. ModelScope（list of model strings → 统一格式）
4. SiliconFlow（list of model objects → 统一格式）
5. IFlow（list of model objects → 统一格式）
""")


def main():
    """主函数"""
    print("=" * 60)
    print("开始分析原始输出格式")
    print("=" * 60)
    
    # 查找所有JSON文件
    output_dir = Path(__file__).parent
    json_files = list(output_dir.glob("*_raw_*.json"))
    
    if not json_files:
        print("❌ 未找到原始输出文件")
        print("请先运行 capture_raw_outputs.py")
        return 1
    
    print(f"找到 {len(json_files)} 个原始输出文件")
    
    # 分析每个文件
    analyses = []
    for json_file in sorted(json_files):
        analysis = analyze_file(json_file)
        analyses.append(analysis)
    
    # 比较分析结果
    valid_analyses = [a for a in analyses if a]
    compare_providers(valid_analyses)
    
    # 生成分析报告
    report_file = output_dir / "analysis_report.md"
    generate_report(valid_analyses, report_file)
    
    print(f"\n📝 详细分析报告已保存到: {report_file}")
    print("\n✅ 分析完成！")
    
    return 0


def generate_report(analyses, report_file):
    """生成分析报告"""
    report = """# 原始输出格式分析报告

## 概述
本报告分析了各个AI模型提供商的原始输出格式，为设计统一返回体提供参考。

## 分析结果

"""
    
    for analysis in analyses:
        provider = analysis['provider']
        report += f"### {provider}\n\n"
        report += f"- **返回类型**: `{analysis['type']}`\n"
        report += f"- **数据结构**: \n```json\n{json.dumps(analysis['structure'], ensure_ascii=False, indent=2)}\n```\n"
        report += f"- **数据样本**: \n```json\n{json.dumps(analysis['sample'], ensure_ascii=False, indent=2)}\n```\n\n"
    
    report += """## 统一格式设计建议

### 当前问题
1. **格式不一致**: 有的返回字典，有的返回列表
2. **字段不统一**: 相同信息使用不同字段名
3. **信息缺失**: 有的提供商缺少分类、描述等信息
4. **嵌套层次不同**: 数据结构深度不一致

### 建议的统一格式
```json
{
  "success": true,
  "provider": "provider_name",
  "timestamp": "2025-12-08T19:55:35",
  "data": {
    "models": [
      {
        "id": "model-id",
        "name": "Model Display Name",
        "provider": "provider_name",
        "category": "text/vision/audio",
        "capabilities": ["chat", "vision"],
        "context_length": 128000,
        "description": "Model description"
      }
    ],
    "categories": {
      "text": ["model-1", "model-2"],
      "vision": ["model-3"]
    }
  },
  "metadata": {
    "total_count": 50,
    "source": "api",
    "raw_format": "list/dict"
  }
}
```

### 各提供商转换方案

1. **智谱AI**
   - 输入: 字典，按分类组织
   - 转换: 展平为模型列表，保留分类信息

2. **OpenRouter**
   - 输入: 模型对象列表
   - 转换: 提取id、name等字段，补充缺失信息

3. **ModelScope**
   - 输入: 模型ID字符串列表
   - 转换: 将字符串转换为模型对象，补充name字段

4. **SiliconFlow**
   - 输入: 模型对象列表
   - 转换: 类似OpenRouter，字段映射

5. **IFlow**
   - 输入: 模型对象列表
   - 转换: 提取modelName/showName/id字段

### 实施步骤
1. 创建统一返回体类/数据结构
2. 修改各个提供商的`fetch_models`方法，返回统一格式
3. 更新测试用例验证统一格式
4. 添加格式转换工具函数
5. 文档更新

---
*报告生成时间: """ + datetime.now().strftime("%Y-%m-%d %H:%M:%S") + """*
"""
    
    with open(report_file, 'w', encoding='utf-8') as f:
        f.write(report)


if __name__ == "__main__":
    try:
        sys.exit(main())
    except KeyboardInterrupt:
        print("\n\n⚠️  用户中断操作")
        sys.exit(1)
    except Exception as e:
        print(f"\n❌ 脚本执行出错: {e}")
        import traceback
        traceback.print_exc()
        sys.exit(1)