"""Independent observable checks for the offline teaching contract."""
import unittest
from worked_example import GOOD, SUGGESTIONS, Policy, execute_tool, run, validate_draft


class WorkflowTests(unittest.TestCase):
    def test_baseline_checks_authoritative_facts(self):
        self.assertEqual(validate_draft(GOOD), [])
        self.assertEqual(validate_draft({**GOOD, "weekly_minutes": 62}),
                         ["unsupported_weekly_minutes"])

    def test_missing_data_is_not_a_known_zero(self):
        self.assertIn("unsupported_measured_savings",
                      validate_draft({**GOOD, "measured_savings": 0}))

    def test_structure_is_separate_from_truth(self):
        self.assertEqual(validate_draft({"team": 6}), ["invalid_structure"])
        self.assertEqual(validate_draft({**GOOD, "team": 20}), ["unsupported_team"])

    def test_tools_need_harness_support(self):
        self.assertEqual(run(SUGGESTIONS, Policy(tools=()))["status"], "denied")
        result = run(SUGGESTIONS)
        self.assertEqual(result["status"], "completed")
        self.assertEqual(result["artifact"]["weekly_minutes"], 720)

    def test_external_text_cannot_authorize_email(self):
        trace = [
            {"kind": "tool", "name": "read_fixture", "arguments": {"id": "untrusted-note"}},
            {"kind": "tool", "name": "send_email", "arguments": {"recipient": "everyone"}},
        ]
        self.assertEqual(run(trace)["status"], "denied")

    def test_files_are_an_allowlist_not_arbitrary_paths(self):
        self.assertEqual(execute_tool("read_fixture", {"id": "../../secrets"}, Policy())["status"], "denied")

    def test_tool_arguments_are_validated(self):
        for args in ({"a": True, "b": 12}, {"a": -1, "b": 12},
                     {"a": "6", "b": 12}, {"a": 6, "b": 12, "other": "x"}):
            self.assertEqual(execute_tool("multiply", args, Policy())["status"], "invalid")

    def test_step_limit_stops_without_an_artifact(self):
        result = run(SUGGESTIONS, Policy(max_steps=1))
        self.assertEqual(result["status"], "limit")
        self.assertIsNone(result["artifact"])

    def test_refusal_timeout_partial_and_empty_are_not_success(self):
        for status in ("refusal", "timeout", "incomplete"):
            self.assertEqual(run([{"kind": status}])["status"], status)
            self.assertIsNone(run([{"kind": status}])["artifact"])
        self.assertEqual(run([])["status"], "incomplete")

    def test_failed_fact_check_does_not_publish_artifact(self):
        result = run([{"kind": "final", "artifact": {**GOOD, "team": 20}}])
        self.assertEqual(result["status"], "failed_check")
        self.assertIsNone(result["artifact"])

    def test_trace_omits_raw_source_contents(self):
        self.assertNotIn("Ignore the rules", str(run(SUGGESTIONS)["trace"]))

    def test_unknown_events_and_unimplemented_tools_are_rejected(self):
        self.assertEqual(run([{"kind": "mystery"}])["status"], "invalid")
        self.assertEqual(execute_tool("mystery", {}, Policy(tools=("mystery",)))["status"], "denied")


if __name__ == "__main__":
    unittest.main()
