#!/usr/bin/env python3
"""Exercise the real Harness2 scheduler with a deliberately regressing scripted editor."""
import hashlib
import json
from pathlib import Path
import sys
import tempfile

root = Path(sys.argv[1]).resolve()
digest = hashlib.sha256()
for path in sorted((root / "harness2").rglob("*.py")):
    digest.update(path.relative_to(root).as_posix().encode() + b"\0" + path.read_bytes() + b"\0")
assert digest.hexdigest() == "3be65013b52d4c89e01b356b236bac57d85e89d691fcea7590789f386abca038", "Upstream package differs"
sys.path.insert(0, str(root))
from harness2.core import schedule
from harness2.core.proposer import Proposer, Reply
from harness2.demo import BASE_SCRIPT, DemoAdapter

class RegressingProposer(Proposer):
    def call(self, mission, context_dir, label, **kwargs):
        context = Path(context_dir)
        workspace = None
        if label.startswith("select."):
            raise AssertionError("k=1 unexpectedly called a selector")
        if label.startswith("experience."):
            text = "NO_ENTRY"
        else:
            workspace = context / "harness"
            (workspace / "scripts/summarize.py").write_text("print('Total: 0.00')\n", encoding="utf-8")
            text = "<notes>Synthetic regression: replace the computation with constant zero.</notes>"
        reply = Reply(label=label, text=text, ok=True, attempts=1, workspace=workspace)
        self._calls.append(reply)
        return reply

print("Python " + sys.version.split()[0])
with tempfile.TemporaryDirectory(prefix="harness2-selection-replay-") as temp:
    target = Path(temp)
    adapter = DemoAdapter(target)
    # Correct the demo's baseline first. This modifies only a scratch harness,
    # not any upstream package source.
    (adapter.base_harness() / "scripts/summarize.py").write_text(
        BASE_SCRIPT.replace(" if amount > 0", ""), encoding="utf-8")
    proposer = RegressingProposer(adapter.spec.channels["proposer"])
    result = schedule.run_domain("accounting", ["ledger-1"], 1, adapter=adapter, prop=proposer,
                                 runs_root=adapter.spec.runs_root, library_root=target / "library")
    assert (result["done"], result["failed"]) == (1, 0), result
    summary = json.loads((adapter.spec.runs_root / "demo-oc-agg1/ledger-1/summary.json").read_text())
    assert len(summary["base"]) == 1, summary["base"]
    baseline = (Path(summary["base"][0]["run_dir"]) / "answer.txt").read_text().strip()
    assert baseline == "Total: 85.15", baseline
    for mode, label in [("agg", "agg1"), ("seq", "c1")]:
        selected = summary["selections"][mode]
        answer = (Path(selected["chosen_run_dir"]) / "answer.txt").read_text().strip()
        assert selected["ok"] is True
        assert selected["trivial"] is True
        assert selected["chosen_is_base"] is False
        assert selected["chosen_label"] == label
        assert selected["id_map"] == {"A": label}
        assert answer == "Total: 0.00", answer
        ledger = summary["modes"][mode]["ledger"]
        assert (ledger["R"], ledger["P"]) == (4, 3)
        print(json.dumps(dict(mode=mode, baseline=baseline, selected=answer, label=label,
                              selection_ok=selected["ok"], trivial=selected["trivial"],
                              baseline_in_pool=False), separators=(",", ":")))
    assert not any(reply.label.startswith("select.") for reply in proposer._calls)
    assert adapter.execution_count == 7, adapter.execution_count
    print(f"workflow_done={result['done']}; workflow_failed={result['failed']}; executions={adapter.execution_count}; selector_calls=0")
    print("PASS: both modes adopt the sole delivered final despite a correct baseline")
