#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
# See LICENSE file for details.
"""
Benchmark Synthesizer: Convert benchmark outcomes to lessons (V43.12)

Pipeline: Benchmark outcome -> Evidence -> Pattern/Lesson -> Brain Map update.
Achieved benchmarks become WIN evidence. Failed become FAIL evidence (weighted 2.5x).

Usage:
    python .claude/automation/benchmark_synthesizer.py --synthesize-all
    python .claude/automation/benchmark_synthesizer.py --synthesize BM-001
    python .claude/automation/benchmark_synthesizer.py --dry-run
Dependencies: Python stdlib only (Law 4)
"""

import json
import sys
from datetime import date, datetime, timezone
from pathlib import Path

# Add Utilities to path for brain_utils

from pulse.core.brain_utils import (load_config, load_json, load_json_dict, save_json,
                         extract_domain, text_similarity,
                         BENCHMARKS_FILE, EVIDENCE_DIR, GROWTH_METRICS,
                         BRAIN_MAP)


def load_benchmarks() -> dict:
    """Load benchmarks file."""
    return load_json_dict(BENCHMARKS_FILE)


def find_completed_benchmarks(data: dict) -> list:
    """Find benchmarks that have outcomes but haven't been synthesized."""
    completed = []
    for bm in data.get("benchmarks", []):
        if bm.get("outcome") and not bm.get("synthesized"):
            completed.append(bm)
    return completed


def benchmark_to_evidence(bm: dict) -> dict:
    """Convert a benchmark outcome to an evidence item."""
    outcome = bm.get("outcome", {})
    result = outcome.get("result", "unknown")
    now = datetime.now(timezone.utc).isoformat()

    evidence = {
        "evidence": f"Benchmark {bm['id']}: {bm.get('description', '')}",
        "type": "win" if result == "achieved" else "fail",
        "source": f"benchmark_tracker/{bm['id']}",
        "date": now,
        "confidence": 0.9 if result == "achieved" else 0.85,
        "pattern": f"benchmark_{result}",
        "tags": ["benchmark", result, bm.get("id", "")],
        "benchmark_id": bm["id"],
        "criteria": bm.get("criteria", ""),
    }

    if result == "achieved":
        evidence["lesson"] = f"Successfully achieved: {bm.get('criteria', '')}"
        if outcome.get("notes"):
            evidence["lesson"] += f". Notes: {outcome['notes']}"
    else:
        evidence["lesson"] = f"Failed to achieve: {bm.get('criteria', '')}"
        if outcome.get("reason"):
            evidence["lesson"] += f". Reason: {outcome['reason']}"

    return evidence


def determine_evidence_file(bm: dict) -> str:
    """Determine which evidence file to append to."""
    desc = bm.get("description", "").lower()
    domain_keywords = {
        "translation": ["translat", "language", "text"],
        "tts": ["voice", "speech", "tts", "audio"],
        "ui": ["ui", "keyboard", "button", "interface"],
        "detection": ["detect", "identify", "classify"],
        "handler": ["handler", "command", "callback"],
    }
    for domain, keywords in domain_keywords.items():
        for kw in keywords:
            if kw in desc:
                return f"{domain}_learnings.json"
    return "benchmark_outcomes.json"


def write_evidence(evidence: dict, evidence_file: str):
    """Append evidence to the appropriate file."""
    EVIDENCE_DIR.mkdir(parents=True, exist_ok=True)
    path = EVIDENCE_DIR / evidence_file
    items = load_json(path)
    if not isinstance(items, list):
        items = []
    items.append(evidence)
    save_json(path, items)
    print(f"  [EVIDENCE] Written to {evidence_file}")


def update_brain_map(bm_id: str, evidence_file: str):
    """Update brain map with benchmark->evidence connection."""
    brain_map = load_json_dict(BRAIN_MAP)
    brain_map.setdefault("benchmark_connections", {})
    brain_map["benchmark_connections"][bm_id] = {
        "evidence_file": f"evidence/{evidence_file}",
        "date": date.today().isoformat()
    }
    save_json(BRAIN_MAP, brain_map)


def update_growth_metrics(bm_id: str, result: str):
    """Update growth metrics with benchmark synthesis."""
    metrics = load_json_dict(GROWTH_METRICS)
    benchmarks = metrics.setdefault("benchmark_synthesis", [])
    benchmarks.append({
        "benchmark_id": bm_id,
        "result": result,
        "date": datetime.now(timezone.utc).isoformat()
    })
    if len(benchmarks) > 100:
        metrics["benchmark_synthesis"] = benchmarks[-50:]
    save_json(GROWTH_METRICS, metrics)


def mark_synthesized(data: dict, bm_id: str):
    """Mark benchmark as synthesized to prevent re-processing."""
    for bm in data.get("benchmarks", []):
        if bm["id"] == bm_id:
            bm["synthesized"] = True
            bm["synthesized_date"] = datetime.now(timezone.utc).isoformat()
            break


def synthesize_benchmark(bm: dict, data: dict, dry_run: bool = False) -> dict:
    """Full synthesis pipeline for one benchmark."""
    evidence = benchmark_to_evidence(bm)
    evidence_file = determine_evidence_file(bm)
    result = bm.get("outcome", {}).get("result", "unknown")

    report = {
        "benchmark_id": bm["id"],
        "result": result,
        "evidence_file": evidence_file,
        "evidence_type": evidence["type"],
        "lesson": evidence.get("lesson", "")
    }

    if not dry_run:
        write_evidence(evidence, evidence_file)
        update_brain_map(bm["id"], evidence_file)
        update_growth_metrics(bm["id"], result)
        mark_synthesized(data, bm["id"])
        save_json(BENCHMARKS_FILE, data)
        print(f"  [SYNTHESIZED] {bm['id']} -> {evidence_file} ({result})")
    else:
        print(f"  [DRY-RUN] {bm['id']} -> {evidence_file} ({result})")

    return report


def synthesize_all(dry_run: bool = False) -> list:
    """Synthesize all completed benchmarks."""
    data = load_benchmarks()
    completed = find_completed_benchmarks(data)
    if not completed:
        print("  No un-synthesized benchmarks found.")
        return []

    reports = []
    for bm in completed:
        report = synthesize_benchmark(bm, data, dry_run)
        reports.append(report)

    summary = {
        "total": len(reports),
        "achieved": sum(1 for r in reports if r["result"] == "achieved"),
        "failed": sum(1 for r in reports if r["result"] == "failed")
    }
    print(f"\n  Summary: {summary['total']} synthesized "
          f"({summary['achieved']} wins, {summary['failed']} fails)")
    return reports


def synthesize_one(bm_id: str, dry_run: bool = False) -> dict:
    """Synthesize a specific benchmark by ID."""
    data = load_benchmarks()
    for bm in data.get("benchmarks", []):
        if bm["id"] == bm_id:
            if not bm.get("outcome"):
                print(f"  [ERROR] {bm_id} has no outcome yet")
                return {}
            if bm.get("synthesized"):
                print(f"  [SKIP] {bm_id} already synthesized")
                return {}
            return synthesize_benchmark(bm, data, dry_run)
    print(f"  [ERROR] {bm_id} not found")
    return {}


# === CLI ===

def main():
    dry_run = "--dry-run" in sys.argv
    print("=== Benchmark Synthesizer V43.12 ===")

    if "--synthesize-all" in sys.argv:
        synthesize_all(dry_run)
        return

    if "--synthesize" in sys.argv:
        idx = sys.argv.index("--synthesize")
        bm_id = sys.argv[idx + 1] if idx + 1 < len(sys.argv) else ""
        synthesize_one(bm_id, dry_run)
        return

    print("  Usage: --synthesize-all | --synthesize BM-XXX [--dry-run]")


if __name__ == "__main__":
    main()
