"""Tests for fw_server.memory_bank — markdown export of HCP context."""

from __future__ import annotations

from pathlib import Path

import pytest

from hcp.protocol import HCPProtocol
from fw_server.memory_bank import sync_memory_bank


SAMPLE_TEXT = "Bismillahirrahmanirrahim.  Kudret-i İlahiye her şeyi ihata eder."


@pytest.fixture()
def state_dir(tmp_path: Path) -> Path:
    d = tmp_path / ".hcp_state"
    d.mkdir()
    return d


@pytest.fixture()
def seeded_proto() -> HCPProtocol:
    p = HCPProtocol()
    p.ingest(SAMPLE_TEXT)
    return p


EXPECTED_FILES = {"activeContext.md", "techContext.md", "sessionLog.md", "progress.md"}


class TestSyncMemoryBank:
    def test_creates_four_files(self, state_dir, seeded_proto):
        result = sync_memory_bank(state_dir, seeded_proto)
        mb_dir = state_dir.parent / "memory-bank"
        assert mb_dir.exists()
        created = {f.name for f in mb_dir.iterdir() if f.is_file()}
        assert EXPECTED_FILES.issubset(created)

    def test_return_dict_structure(self, state_dir, seeded_proto):
        result = sync_memory_bank(state_dir, seeded_proto)
        assert "action" in result
        assert "memory_bank_dir" in result
        assert "files_written" in result
        assert "timestamp" in result
        assert isinstance(result["files_written"], list)
        assert len(result["files_written"]) >= 4

    def test_overwrite_on_second_sync(self, state_dir, seeded_proto):
        sync_memory_bank(state_dir, seeded_proto)
        sync_memory_bank(state_dir, seeded_proto)
        mb_dir = state_dir.parent / "memory-bank"
        # Still exactly the expected files, not doubled
        created = {f.name for f in mb_dir.iterdir() if f.is_file()}
        assert EXPECTED_FILES.issubset(created)

    def test_session_log_append_only(self, state_dir, seeded_proto):
        sync_memory_bank(state_dir, seeded_proto, session_note="First sync")
        mb_dir = state_dir.parent / "memory-bank"
        log1 = (mb_dir / "sessionLog.md").read_text(encoding="utf-8")

        sync_memory_bank(state_dir, seeded_proto, session_note="Second sync")
        log2 = (mb_dir / "sessionLog.md").read_text(encoding="utf-8")

        assert "First sync" in log2
        assert "Second sync" in log2
        assert len(log2) > len(log1)

    def test_session_note_appears(self, state_dir, seeded_proto):
        sync_memory_bank(state_dir, seeded_proto, session_note="Custom note here")
        mb_dir = state_dir.parent / "memory-bank"
        log_text = (mb_dir / "sessionLog.md").read_text(encoding="utf-8")
        assert "Custom note here" in log_text


class TestActiveContext:
    def test_contains_hcp_heading(self, state_dir, seeded_proto):
        sync_memory_bank(state_dir, seeded_proto)
        mb_dir = state_dir.parent / "memory-bank"
        text = (mb_dir / "activeContext.md").read_text(encoding="utf-8")
        assert "Active Context" in text or "HCP" in text

    def test_contains_chunk_count(self, state_dir, seeded_proto):
        sync_memory_bank(state_dir, seeded_proto)
        mb_dir = state_dir.parent / "memory-bank"
        text = (mb_dir / "activeContext.md").read_text(encoding="utf-8")
        # Should mention either 'chunk' or count somewhere
        assert "chunk" in text.lower() or str(len(seeded_proto._chunks)) in text


class TestTechContext:
    def test_contains_config_info(self, state_dir, seeded_proto):
        sync_memory_bank(state_dir, seeded_proto)
        mb_dir = state_dir.parent / "memory-bank"
        text = (mb_dir / "techContext.md").read_text(encoding="utf-8")
        assert "Chunk size" in text or "HCP Configuration" in text


class TestProgress:
    def test_contains_workflow_info(self, state_dir, seeded_proto):
        sync_memory_bank(state_dir, seeded_proto)
        mb_dir = state_dir.parent / "memory-bank"
        text = (mb_dir / "progress.md").read_text(encoding="utf-8")
        assert "Progress" in text or "Workflow" in text or "workflow" in text


class TestEmptyProtocol:
    def test_sync_empty_protocol(self, state_dir):
        """sync_memory_bank should work even if protocol has no data."""
        p = HCPProtocol()
        result = sync_memory_bank(state_dir, p)
        assert result["action"] in ("synced", "skipped", "sync_memory_bank")
