from __future__ import annotations

import argparse
import json
from pathlib import Path


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("--protocol", type=Path, required=True)
    parser.add_argument("--openai", type=Path, required=True)
    parser.add_argument("--anthropic", type=Path, required=True)
    parser.add_argument("--core-replay", type=Path, required=True)
    parser.add_argument("--offline-mutation", type=Path, required=True)
    parser.add_argument("--output", type=Path, required=True)
    args = parser.parse_args()

    protocol = json.loads(args.protocol.read_text(encoding="utf-8"))
    openai = json.loads(args.openai.read_text(encoding="utf-8"))
    anthropic = json.loads(args.anthropic.read_text(encoding="utf-8"))
    core = json.loads(args.core_replay.read_text(encoding="utf-8"))
    mutation = json.loads(args.offline_mutation.read_text(encoding="utf-8"))
    provider_results = [openai, anthropic]
    expected_hash = protocol["design"]["expected_schedule_hash"]
    if any(item["schedule_hash"] != expected_hash for item in provider_results):
        raise RuntimeError("Provider analyses do not share the frozen schedule")
    new_trials = sum(item["scheduled_trials"] for item in provider_results)
    new_successes = sum(item["strict_successes"] for item in provider_results)
    external_policy_evaluations = sum(
        item["policy_proposal_evaluations"] for item in provider_results
    )
    preserved_reference_evaluations = int(
        core["capability_policy_evaluations"]
    )
    total_policy_evaluations = (
        preserved_reference_evaluations
        + int(core["capability_policy_evaluations"])
        + external_policy_evaluations
    )
    output = {
        "schema_version": "1.0",
        "protocol_id": protocol["protocol_id"],
        "external_provider_trials": new_trials,
        "external_strict_successes": new_successes,
        "external_strict_failures": new_trials - new_successes,
        "external_containment_failures": sum(
            item["containment_failures"] for item in provider_results
        ),
        "external_policy_disagreements": sum(
            item["policy_disagreements"] for item in provider_results
        ),
        "external_policy_proposal_evaluations": external_policy_evaluations,
        "preserved_core_reference_policy_evaluations": (
            preserved_reference_evaluations
        ),
        "preserved_core_capability_policy_replays": int(
            core["capability_policy_evaluations"]
        ),
        "total_policy_proposal_evaluations": total_policy_evaluations,
        "total_completed_provider_trials_including_prior_core": (
            new_trials + preserved_reference_evaluations
        ),
        "total_cost_usd": round(
            sum(item["total_completed_cost_usd"] for item in provider_results),
            8,
        ),
        "overall_acceptance_rule_passed": (
            new_trials == 800
            and new_successes == 800
            and all(
                item["provider_acceptance_rule_passed"]
                for item in provider_results
            )
            and core["strict_failures"] == 0
            and core["containment_failures"] == 0
        ),
        "provider_results": [
            {
                key: value
                for key, value in item.items()
                if key != "trials"
            }
            for item in provider_results
        ],
        "core_capability_replay": {
            key: value
            for key, value in core.items()
            if key != "providers"
        },
        "offline_mutation_summary": [
            {
                key: value
                for key, value in item.items()
                if key
                in {
                    "policy",
                    "corpus",
                    "reference_cases",
                    "operator_count",
                    "core_killed",
                    "expanded_killed",
                    "core_mutation_score",
                    "expanded_mutation_score",
                }
            }
            for item in mutation["reports"]
        ],
        "claim_boundary": protocol["claim_boundary"],
        "reporting_commitment": protocol["reporting_commitment"],
    }
    args.output.parent.mkdir(parents=True, exist_ok=True)
    args.output.write_text(
        json.dumps(output, indent=2, sort_keys=True) + "\n",
        encoding="utf-8",
    )
    print(json.dumps(output, indent=2, sort_keys=True))


if __name__ == "__main__":
    main()
