#!/usr/bin/env python3
from __future__ import annotations

import tempfile
import unittest
from pathlib import Path

from case_storage import CaseStorage, ForensicsHostMismatchError


class CaseStorageHayabusaLinkTest(unittest.TestCase):
    def test_link_hayabusa_metadata(self) -> None:
        with tempfile.TemporaryDirectory() as tmpdir:
            db_path = Path(tmpdir) / "cases.db"
            storage = CaseStorage(db_path)
            created = storage.create_case(
                {
                    "incident_id": "inc-1",
                    "host": "SHARKON2025",
                    "title": "DLP print incident",
                    "severity": "high",
                },
                actor="test",
            )
            linked = storage.link_hayabusa(
                case_id=int(created["id"]),
                payload={
                    "host": "SHARKON2025",
                    "mode": "incident",
                    "status": "ok",
                    "intake_id": "pkg-1",
                    "report_dir": "/opt/hayabusa/reports/SHARKON2025/run-1",
                    "package_path": "/opt/hayabusa/archive/packages/SHARKON2025/pkg-1.zip",
                    "sha256": "abc123",
                    "link_source": "unit-test",
                },
                actor="test",
            )
            hayabusa = (linked.get("forensics") or {}).get("hayabusa") or {}
            self.assertEqual(hayabusa.get("tool"), "hayabusa")
            self.assertEqual(hayabusa.get("host"), "SHARKON2025")
            self.assertEqual(hayabusa.get("mode"), "incident")
            self.assertEqual(hayabusa.get("status"), "ok")
            self.assertEqual(hayabusa.get("intake_id"), "pkg-1")
            self.assertEqual(hayabusa.get("link_source"), "unit-test")
            audit = storage.list_audit(int(created["id"]))
            self.assertTrue(any(row.get("action") == "link_hayabusa" for row in audit))

    def test_create_case_deduplicates_by_incident_and_host(self) -> None:
        with tempfile.TemporaryDirectory() as tmpdir:
            db_path = Path(tmpdir) / "cases.db"
            storage = CaseStorage(db_path)
            payload = {
                "incident_id": "2026-05-14T17:00:52.186Z|self_test|Администратор|||",
                "host": "SHARKON2025",
                "title": "DLP self_test · Администратор",
                "severity": "medium",
            }
            created = storage.create_case(payload, actor="test")
            duplicate = storage.create_case(payload, actor="test")
            self.assertEqual(created["id"], duplicate["id"])
            cases = storage.list_cases(host="SHARKON2025", limit=10)
            self.assertEqual(len(cases), 1)

    def test_link_hayabusa_rejects_host_mismatch(self) -> None:
        with tempfile.TemporaryDirectory() as tmpdir:
            db_path = Path(tmpdir) / "cases.db"
            storage = CaseStorage(db_path)
            created = storage.create_case(
                {
                    "incident_id": "inc-2",
                    "host": "SHARKON2025",
                    "title": "DLP print incident",
                    "severity": "high",
                },
                actor="test",
            )
            with self.assertRaises(ForensicsHostMismatchError):
                storage.link_hayabusa(
                    case_id=int(created["id"]),
                    payload={
                        "host": "stability",
                        "mode": "incident",
                        "status": "ok",
                        "intake_id": "pkg-2",
                        "report_dir": "/opt/hayabusa/reports/stability/run-1",
                    },
                    actor="test",
                )


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