#!/usr/bin/env python3
"""Cross-repo integration demo for abi-evals.

Simulates a mock orchestration step:
1. Creates a synthetic PlanGraph
2. Builds a mock evidence pack with policy decisions and artifacts
3. Runs eval suite against the evidence pack
4. Emits events.ndjson (abi-observability compatible)
5. Outputs a small evidence-pack-like folder

Runs entirely offline. Does not require other abi-* repos to be installed.
"""
from __future__ import annotations

import json
import sys
import tempfile
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent / "src"))

from abi_evals.goldens import diff_golden
from abi_evals.runner import run_suite, write_results

REPO_ROOT = Path(__file__).resolve().parent.parent.parent

FIXED_TS = "2025-01-01T00:00:00Z"
RUN_ID = "e2e00001"


def make_synthetic_plan_graph() -> dict:
    """Create a small synthetic PlanGraph (plan-graph/1.0 compatible)."""
    return {
        "schema_version": "plan-graph/1.0",
        "run_id": RUN_ID,
        "description": "Demo plan graph for eval harness",
        "nodes": [
            {
                "node_id": "step-1",
                "name": "Generate artifacts",
                "depends_on": [],
                "status": "completed",
                "agent": "builder",
                "metadata": {"node_type": "AGENT_TASK"},
            },
            {
                "node_id": "step-2",
                "name": "Run evaluation",
                "depends_on": ["step-1"],
                "status": "pending",
                "agent": "evaluator",
                "metadata": {"node_type": "EVAL_RUN"},
            },
            {
                "node_id": "step-3",
                "name": "Check regression gate",
                "depends_on": ["step-2"],
                "status": "pending",
                "agent": "validator",
                "metadata": {"node_type": "GATE_CHECK"},
            },
        ],
    }


def make_mock_evidence_pack() -> dict:
    """Create a mock evidence pack with artifacts to evaluate."""
    return {
        "run_id": RUN_ID,
        "artifacts": {
            "greeting": "Hello, World!",
            "sum_result": 42,
            "config": {"debug": False, "version": "1.0.0"},
            "analysis": "The code is well-structured and follows best practices.",
        },
        "policy_decisions": [
            {"decision": "allow", "tool": "read_file"},
            {"decision": "allow", "tool": "write_file"},
            {"decision": "deny", "tool": "shell_exec"},
        ],
    }


def make_eval_suite() -> dict:
    """Create a comprehensive eval suite exercising all comparator types."""
    return {
        "schema_version": "eval-suite/1.0",
        "suite_id": "cross-repo-e2e",
        "description": "Cross-repo integration eval suite",
        "cases": [
            {
                "case_id": "exact-greeting",
                "description": "Exact match on greeting artifact",
                "input": "Hello, World!",
                "expected": "Hello, World!",
                "comparison": "exact",
            },
            {
                "case_id": "numeric-sum",
                "description": "Numeric tolerance on sum result",
                "input": 42.0001,
                "expected": 42.0,
                "comparison": "numeric_tolerance",
                "tolerance": 0.01,
            },
            {
                "case_id": "structural-config",
                "description": "Structural match on config",
                "input": {"debug": False, "version": "1.0.0", "extra": "ignored"},
                "expected": {"debug": False, "version": "1.0.0"},
                "comparison": "structural",
            },
            {
                "case_id": "regex-analysis",
                "description": "Regex assertion on analysis text",
                "input": "The code is well-structured and follows best practices.",
                "expected": ["well-structured", "best practices"],
                "comparison": "regex_assert",
            },
            {
                "case_id": "presence-artifacts",
                "description": "Verify required artifacts present",
                "input": {"greeting": True, "sum_result": True, "config": True},
                "expected": ["greeting", "sum_result", "config"],
                "comparison": "presence_assert",
            },
            {
                "case_id": "schema-manifest",
                "description": "Validate manifest structure",
                "input": {
                    "schema_version": "evidence-pack-manifest/1.0",
                    "run_id": RUN_ID,
                    "created_at": FIXED_TS,
                },
                "expected": {"$required_keys": ["schema_version", "run_id", "created_at"]},
                "comparison": "schema_validate",
            },
        ],
    }


def main() -> None:
    print("=== abi-evals Cross-Repo Integration Demo ===\n")

    # 1. Create synthetic PlanGraph
    print("--- Step 1: Create PlanGraph ---")
    plan_graph = make_synthetic_plan_graph()
    print(f"  Nodes: {len(plan_graph['nodes'])}")

    # 2. Create mock evidence pack
    print("\n--- Step 2: Create Evidence Pack ---")
    evidence = make_mock_evidence_pack()
    print(f"  Artifacts: {list(evidence['artifacts'].keys())}")
    print(f"  Policy decisions: {len(evidence['policy_decisions'])}")

    # 3. Run eval suite
    print("\n--- Step 3: Run Eval Suite ---")
    suite = make_eval_suite()
    results = run_suite(suite, evidence_pack=evidence, run_id=RUN_ID, timestamp=FIXED_TS)
    print(f"  Total: {results['summary']['total']}")
    print(f"  Passed: {results['summary']['passed']}")
    print(f"  Failed: {results['summary']['failed']}")

    for r in results["results"]:
        icon = {"pass": "OK", "fail": "XX", "error": "!!", "skipped": "--"}[r["status"]]
        print(f"  [{icon}] {r['case_id']}: {r['message'][:60]}")

    # 4. Diff against golden baseline
    print("\n--- Step 4: Golden Diff ---")
    golden_set = {
        "version": "e2e-v1",
        "artifacts": {
            "greeting": "Hello, World!",
            "sum_result": 42,
        },
    }
    diffs = diff_golden(golden_set, evidence)
    for d in diffs:
        icon = {"match": "OK", "mismatch": "XX", "missing_golden": "??", "missing_actual": "!!"}
        print(f"  [{icon.get(d['status'], '??')}] {d['key']}: {d['details']}")

    # 5. Write evidence-pack-like folder
    with tempfile.TemporaryDirectory() as tmp:
        pack_dir = Path(tmp) / f"evidence_pack_{RUN_ID}"
        pack_dir.mkdir(parents=True)

        print("\n--- Step 5: Write Evidence Pack ---")

        # plan_graph.json
        with open(pack_dir / "plan_graph.json", "w") as f:
            json.dump(plan_graph, f, indent=2, sort_keys=True)
            f.write("\n")
        print("  plan_graph.json")

        # eval_results.json
        write_results(results, pack_dir / "eval_results.json")
        print("  eval_results.json")

        # policy_decisions.ndjson
        with open(pack_dir / "policy_decisions.ndjson", "w") as f:
            for pd in evidence["policy_decisions"]:
                record = {
                    "schema_version": "tier2-policy-decision/1.0",
                    "run_id": RUN_ID,
                    "policy_id": "default",
                    "decision": pd["decision"],
                    "decided_at": FIXED_TS,
                    "reason": f"Tool: {pd['tool']}",
                    "context": {"tool": pd["tool"]},
                }
                f.write(json.dumps(record, sort_keys=True) + "\n")
        print("  policy_decisions.ndjson")

        # events.ndjson (observability-compatible)
        events = [
            {
                "schema_version": "tier2-event-envelope/1.0",
                "event_id": "evt-001",
                "event_type": "RUN_STARTED",
                "timestamp": FIXED_TS,
                "run_id": RUN_ID,
                "payload": {"message": "Eval demo started"},
                "metadata": {},
            },
            {
                "schema_version": "tier2-event-envelope/1.0",
                "event_id": "evt-002",
                "event_type": "EVAL_COMPLETED",
                "timestamp": "2025-01-01T00:00:03Z",
                "run_id": RUN_ID,
                "payload": {
                    "suite_id": suite["suite_id"],
                    "passed": results["summary"]["passed"],
                    "failed": results["summary"]["failed"],
                },
                "metadata": {},
            },
            {
                "schema_version": "tier2-event-envelope/1.0",
                "event_id": "evt-003",
                "event_type": "RUN_COMPLETED",
                "timestamp": "2025-01-01T00:00:05Z",
                "run_id": RUN_ID,
                "payload": {"status": "success"},
                "metadata": {},
            },
        ]
        with open(pack_dir / "events.ndjson", "w") as f:
            for evt in events:
                f.write(json.dumps(evt, sort_keys=True) + "\n")
        print(f"  events.ndjson ({len(events)} events)")

        # manifest.json
        manifest = {
            "schema_version": "tier2-pack-manifest/1.0",
            "run_id": RUN_ID,
            "created_at": FIXED_TS,
            "components": {
                "plan_graph": "plan_graph.json",
                "eval_results": "eval_results.json",
                "policy_decisions": "policy_decisions.ndjson",
                "events": "events.ndjson",
            },
            "summary": {
                "total_files": 4,
                "total_artifacts": 0,
            },
        }
        with open(pack_dir / "manifest.json", "w") as f:
            json.dump(manifest, f, indent=2, sort_keys=True)
            f.write("\n")
        print("  manifest.json")

        print("\n--- Evidence Pack Contents ---")
        for item in sorted(pack_dir.iterdir()):
            print(f"  {item.name} ({item.stat().st_size} bytes)")

    print("\nCross-repo integration demo complete.")


if __name__ == "__main__":
    main()
