"""Claude-Adapter über den bestehenden Kanal (Mock-Plugin), keine zweite Claude-Instanz."""
import tempfile
import unittest
from pathlib import Path

from aria_router.adapter_contract import ResultStatus
from aria_router.claude_channel import CHANNEL_METHOD, FORWARD_ACTION, ClaudeChannelAdapter
from aria_router.context import MemorySnippet
from aria_router.gateway import Handling

from tests.helpers import OWNER_ID, AdapterHarness, GatewayTestCase, RecordingSink, document, photo


class ClaudeChannelTests(unittest.TestCase):
    def setUp(self):
        self._tmp = tempfile.TemporaryDirectory()
        self.h = AdapterHarness(Path(self._tmp.name))

    def tearDown(self):
        self._tmp.cleanup()

    def forward(self, job, sink=None):
        adapter = ClaudeChannelAdapter(self.h.verifier, sink=sink)
        return adapter.execute(self.h.clear(adapter, job), job)

    def test_forward_instruction_for_text(self):
        result = self.forward(self.h.job("Hallo Aria"))
        self.assertEqual(result.status, ResultStatus.FORWARD)
        instruction = result.forward
        self.assertEqual((instruction["action"], instruction["method"]), (FORWARD_ACTION, CHANNEL_METHOD))
        self.assertEqual(instruction["params"], {
            "content": "Hallo Aria",
            "meta": {"chat_id": OWNER_ID, "message_id": "7", "user": "kais_test", "user_id": OWNER_ID,
                     "ts": "2026-10-24T18:00:00.000Z"},
        })
        self.assertEqual(instruction["clearance"]["backend"], "claude")
        self.assertEqual(len(instruction["clearance"]["mac"]), 64)

    def test_forward_meta_photo_like_handle_inbound(self):
        meta = self.forward(self.h.job("(photo)", attachments=[photo("/inbox/1-a.jpg")])).forward["params"]["meta"]
        self.assertEqual(meta["image_path"], "/inbox/1-a.jpg")
        self.assertFalse(any(key.startswith("attachment_") for key in meta))

    def test_forward_meta_document_like_handle_inbound(self):
        meta = self.forward(self.h.job("(document: a.pdf)", attachments=[document("a.pdf")])).forward["params"]["meta"]
        self.assertEqual((meta["attachment_kind"], meta["attachment_file_id"], meta["attachment_size"],
                          meta["attachment_mime"], meta["attachment_name"]),
                         ("document", "BQACdoc", "2048", "application/pdf", "a.pdf"))

    def test_username_falls_back_to_id(self):
        meta = self.forward(self.h.job("hallo", username=None)).forward["params"]["meta"]
        self.assertEqual(meta["user"], OWNER_ID)

    def test_memory_not_supported(self):
        adapter = ClaudeChannelAdapter(self.h.verifier)
        job = self.h.job("hallo", memory=[MemorySnippet("brain/a", "x")])
        self.assertEqual(adapter.execute(None, job).error_code, "MEMORY_NOT_SUPPORTED")

    def test_sink_executes_exactly_once(self):
        sink = RecordingSink()
        result = self.forward(self.h.job("hallo"), sink)
        self.assertEqual(len(sink.delivered), 1)
        self.assertEqual(sink.delivered[0]["params"], result.forward["params"])

    def test_sink_failure_reported(self):
        result = self.forward(self.h.job("hallo"), RecordingSink(fail=True))
        self.assertEqual((result.status, result.error_code), (ResultStatus.FAILED, "DELIVERY_FAILED"))

    def test_forward_without_clearance_impossible(self):
        sink = RecordingSink()
        adapter = ClaudeChannelAdapter(self.h.verifier, sink=sink)
        self.assertEqual(adapter.execute(None, self.h.job("hallo")).error_code, "MISSING_CLEARANCE")
        self.assertEqual(sink.delivered, [])


class GatewayClaudeTests(GatewayTestCase):
    def test_gateway_forward_end_to_end(self):
        gateway = self.gateway()
        result = gateway.handle(self.request(1, "Hallo Aria, was steht heute an?"))
        self.assertEqual((result.handling, result.backend), (Handling.FORWARD_TO_CLAUDE_CHANNEL, "claude"))
        self.assertEqual(len(self.sink.delivered), 1)
        self.assertEqual(self.sink.delivered[0]["params"]["content"], "Hallo Aria, was steht heute an?")
        self.assertEqual(result.forward["params"], self.sink.delivered[0]["params"])

    def test_status_quo_everything_unclassified_reaches_claude(self):
        gateway = self.gateway()
        texts = ["Bitte debug mein Python", "yes abcde", "/something", "Pfad /home/aria/brain", "Angebot BMW"]
        for index, text in enumerate(texts, 10):
            with self.subTest(text=text):
                self.assertEqual(gateway.handle(self.request(index, text)).handling,
                                 Handling.FORWARD_TO_CLAUDE_CHANNEL)
        self.assertEqual(len(self.sink.delivered), len(texts))


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