#!/usr/bin/env python3
"""
CangjieMagic Agent DSL → lambdagent 静态分析审计

演示: 用 lambdagent 的 lint + type_check + cost_predict
检查 CangjieMagic Agent 定义中的潜在问题。

用法:
    cd demo/cangjiemagic-audit
    python3 run_audit.py
"""

import os
import sys
import yaml

# 确保能 import lambdagent
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
sys.path.insert(0, project_root)

from lambdagent.fromconfig.lint import lint_config
from lambdagent.fromconfig.schema import validate_schema
from lambdagent.primitives import Lam, Compose, Loop, Tool
from lambdagent.extensions import Par, Route, Guard
from lambdagent.cost_grade import estimate_cost, format_cost_estimate


def load_yaml(path):
    with open(path, "r", encoding="utf-8") as f:
        return yaml.safe_load(f)


def audit_one(name, cfg):
    """审计单个 Agent 配置。"""
    print(f"\n{'─' * 60}")
    print(f"  {name}")
    print(f"  来源: CangjieMagic {cfg.get('_original_file', '?')}")
    print(f"{'─' * 60}")

    # Schema 校验
    schema_issues = validate_schema(cfg)
    for level, rule, msg in schema_issues:
        if level == "ERROR":
            print(f"  [SCHEMA] {rule}: {msg}")

    # Lint 检查
    results = lint_config(cfg)
    errors = [r for r in results if r.level == "ERROR"]
    warnings = [r for r in results if r.level == "WARN"]
    infos = [r for r in results if r.level == "INFO"]

    for r in errors:
        print(f"  [x] ERROR  {r.rule}  {r.message}")
    for r in warnings:
        print(f"  [!] WARN   {r.rule}  {r.message}")
    for r in infos[:2]:
        print(f"  [i] INFO   {r.rule}  {r.message}")

    if not errors and not warnings:
        print(f"  ✅ 无问题")

    print(f"  → {len(errors)} errors, {len(warnings)} warnings, {len(infos)} info")
    return len(errors), len(warnings)


def cost_predict(name, term):
    """成本预测。"""
    grade = estimate_cost(term)
    print(f"\n  {name}:")
    print(f"  {format_cost_estimate(grade)}")
    return grade


def main():
    print("=" * 60)
    print("  CangjieMagic Agent DSL → lambdagent 静态审计")
    print("=" * 60)

    # 加载翻译后的 YAML
    translated_dir = os.path.join(os.path.dirname(__file__), "translated")
    yamls = {}
    for fname in sorted(os.listdir(translated_dir)):
        if fname.endswith(".yml"):
            path = os.path.join(translated_dir, fname)
            yamls[fname] = load_yaml(path)

    # ═══ Part 1: Lint 审计 ═══
    print("\n" + "═" * 60)
    print("  Part 1: 结构安全检查 (lint)")
    print("═" * 60)

    total_e, total_w = 0, 0
    for fname, cfg in yamls.items():
        e, w = audit_one(cfg.get("name", fname), cfg)
        total_e += e
        total_w += w

    # ═══ Part 2: 成本预测 ═══
    print("\n" + "═" * 60)
    print("  Part 2: 成本预测 (Paper III 分级类型)")
    print("═" * 60)

    # WeatherAssistant: react:5, ollama
    cost_predict("WeatherAssistant (react:5, ollama:phi3)",
                 Loop(Lam("weather", "天气查询", model="ollama"),
                      condition=lambda r, s: False, max_steps=5))

    # ResearchAssistant: react:10, deepseek
    cost_predict("ResearchAssistant (react:10, deepseek-chat)",
                 Loop(Compose(Lam("research", "研究分析", model="deepseek-chat"),
                              Tool("search", lambda x: x)),
                      condition=lambda r, s: False, max_steps=10))

    # RouterAgent: deepseek classifier + 2 routes
    cost_predict("DispatchAgent (router, deepseek-chat)",
                 Route(Lam("classify", "分类", model="deepseek-chat"),
                       {"primary": Lam("p", "快速", model="ollama"),
                        "secondary": Lam("s", "深入", model="deepseek-chat")}))

    # ═══ 总结 ═══
    print("\n" + "═" * 60)
    print("  总结")
    print("═" * 60)
    print(f"\n  {len(yamls)} 个 CangjieMagic Agent 配置:")
    print(f"    {total_e} 个 ERROR")
    print(f"    {total_w} 个 WARN")
    print(f"\n  CangjieMagic 仓颉编译器: 不检查这些问题")
    print(f"  lambdagent lint:         编译时全部发现")
    print(f"\n  文件位置:")
    print(f"    原始代码: original/*.cj")
    print(f"    翻译配置: translated/*.yml")


if __name__ == "__main__":
    main()
