from __future__ import annotations

import contextlib
import io
import json
import tempfile
import unittest
from pathlib import Path
from unittest import mock

from donate import describe


class DescribeTests(unittest.TestCase):
    def test_minimal_prompts_auto_accepts_detected_agent_model_org(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp)
            session = root / "session.redacted.jsonl"
            session.write_text("{}\n", encoding="utf-8")
            auto = root / "auto.json"
            auto.write_text(json.dumps({
                "agent": "Codex CLI",
                "model": "gpt-5",
                "org": "OpenAI",
                "turns": 42,
                "records": 123,
                "compactions": 0,
                "source_format": "codex-cli-jsonl",
                "path": str(root / "source.jsonl"),
                "session_label": "Example project · 6980",
                "conversation_fingerprint": "conv-abc123",
                "fingerprint_version": "structure-v1",
            }), encoding="utf-8")

            answers = iter(["agentic-coding", "Python", "donor-handle"])
            with mock.patch("builtins.input", side_effect=lambda _prompt: next(answers)):
                with contextlib.redirect_stdout(io.StringIO()):
                    rc = describe.main([
                        "--session", str(session),
                        "--auto", str(auto),
                        "--minimal-prompts",
                    ])

            manifest = json.loads((root / "session.manifest.json").read_text())

        self.assertEqual(rc, 0)
        self.assertEqual(manifest["agent"], "Codex CLI")
        self.assertEqual(manifest["model"], "gpt-5")
        self.assertEqual(manifest["org"], "OpenAI")
        self.assertEqual(manifest["domain"], "agentic-coding")
        self.assertEqual(manifest["language"], "Python")
        self.assertEqual(manifest["contributor"], "donor-handle")
        self.assertTrue(manifest["session_id"].startswith("donation-"))
        self.assertEqual(manifest["source_session_id"], describe.source_session_id({"path": str(root / "source.jsonl")}))
        self.assertEqual(manifest["source_session_label"], "Example project · 6980")
        self.assertEqual(manifest["source_display_id"], "6980")
        self.assertEqual(manifest["conversation_fingerprint"], "conv-abc123")
        self.assertEqual(manifest["fingerprint_version"], "structure-v1")
        self.assertEqual(manifest["turns"], 42)
        self.assertEqual(manifest["records"], 123)
        self.assertEqual(manifest["source_format"], "codex-cli-jsonl")
        self.assertEqual(manifest["privacy_tier"], "full_redacted")
        self.assertIn("persona_drift_benchmarking", manifest["allowed_uses"])

    def test_write_manifest_normalizes_unknown_language_and_count_types(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp)
            session = root / "session.redacted.jsonl"
            session.write_text("{}\n", encoding="utf-8")

            _, _, manifest = describe.write_manifest_and_consent(
                session,
                {
                    "agent": "Codex CLI",
                    "model": "gpt-5",
                    "org": "OpenAI",
                    "records": "12",
                    "turns": "3",
                    "compactions": "1",
                },
                domain="agentic-coding",
                language="unknown",
                contributor="donor",
            )

        self.assertEqual(manifest["language"], "mixed")
        self.assertEqual(manifest["records"], 12)
        self.assertEqual(manifest["turns"], 3)
        self.assertEqual(manifest["compactions"], 1)
        self.assertNotEqual(manifest["session_id"], "S?")


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