"""
test_phase2.py — 測試 MemosCapturer, FolderCapturer, NoteRepository, TaggingEventRepository
"""
import json
import sys
import tempfile
from pathlib import Path

# 讓 pytest 能找到 src/
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))

import pytest
from capturers.base import RawNote
from capturers.folder import FolderCapturer
from db.repository import NoteRepository, TaggingEventRepository, open_repositories
from db.schema import init_db


# ──────────────────────────────────────────────
# FolderCapturer 測試
# ──────────────────────────────────────────────

def test_folder_capturer_basic(tmp_path):
    """掃描有 .md 檔案的資料夾"""
    (tmp_path / "note1.md").write_text("# Hello\n#python #test\nSome content here.", encoding="utf-8")
    (tmp_path / "note2.md").write_text("## World\nAnother note content here.", encoding="utf-8")
    registry = tmp_path / "registry.json"

    capturer = FolderCapturer(tmp_path, registry_path=registry)
    notes = capturer.fetch()
    assert len(notes) == 2
    sources = {n.source for n in notes}
    assert sources == {"folder"}


def test_folder_capturer_tags():
    """擷取 frontmatter tags 和 inline hashtags"""
    import tempfile, os
    with tempfile.TemporaryDirectory() as d:
        p = Path(d)
        (p / "tagged.md").write_text(
            "---\ntags: [ai, llm]\n---\n# Note\n#python content here long enough.",
            encoding="utf-8"
        )
        capturer = FolderCapturer(p, registry_path=p / "reg.json")
        notes = capturer.fetch()
        assert len(notes) == 1
        tags = set(notes[0].tags_raw)
        assert "ai" in tags
        assert "llm" in tags
        assert "python" in tags


def test_folder_capturer_incremental(tmp_path):
    """第二次 fetch 應只回傳新增或修改的檔案"""
    registry = tmp_path / "registry.json"
    (tmp_path / "a.md").write_text("First file content here!", encoding="utf-8")
    capturer = FolderCapturer(tmp_path, registry_path=registry)
    notes1 = capturer.fetch()
    assert len(notes1) == 1

    # 新增第二個檔案
    (tmp_path / "b.md").write_text("Second file content here!", encoding="utf-8")
    notes2 = capturer.fetch()
    assert len(notes2) == 1
    assert notes2[0].source_id != notes1[0].source_id


def test_folder_capturer_skips_short(tmp_path):
    """太短的內容應被過濾"""
    (tmp_path / "short.md").write_text("hi", encoding="utf-8")
    (tmp_path / "ok.md").write_text("This content is long enough!", encoding="utf-8")
    capturer = FolderCapturer(tmp_path, registry_path=tmp_path / "reg.json")
    notes = capturer.fetch()
    assert len(notes) == 1
    assert "long enough" in notes[0].content


# ──────────────────────────────────────────────
# Repository 測試
# ──────────────────────────────────────────────

@pytest.fixture
def repos(tmp_path):
    db_path = tmp_path / "test.db"
    note_repo, tag_repo = open_repositories(db_path)
    return note_repo, tag_repo


def test_note_upsert_and_get(repos):
    note_repo, _ = repos
    note_repo.upsert(
        note_id="memos-20260101-abc",
        source="memos",
        source_id="abc",
        created_at="2026-01-01T00:00:00+00:00",
        file_path="/vault/test.md",
    )
    row = note_repo.get("memos-20260101-abc")
    assert row is not None
    assert row["source"] == "memos"
    assert note_repo.count() == 1


def test_note_upsert_idempotent(repos):
    note_repo, _ = repos
    note_repo.upsert("id1", "folder", "x1", "2026-01-01T00:00:00+00:00", "/a.md")
    note_repo.upsert("id1", "folder", "x1", "2026-01-01T00:00:00+00:00", "/a.md", content_hash="abc")
    assert note_repo.count() == 1
    row = note_repo.get("id1")
    assert row["content_hash"] == "abc"


def test_tagging_event_insert_and_list(repos):
    note_repo, tag_repo = repos
    note_repo.upsert("n1", "memos", "m1", "2026-01-01T00:00:00+00:00", "/n1.md")

    eid = tag_repo.insert("n1", "ai", agent="ai", ai_model="gpt-4", ai_rationale="relevant")
    assert eid > 0

    events = tag_repo.list_by_note("n1")
    assert len(events) == 1
    assert events[0]["tag"] == "ai"
    assert events[0]["review_status"] == "pending"


def test_tagging_event_update_status(repos):
    note_repo, tag_repo = repos
    note_repo.upsert("n2", "memos", "m2", "2026-01-01T00:00:00+00:00", "/n2.md")
    eid = tag_repo.insert("n2", "llm", agent="ai")
    ok = tag_repo.update_status(eid, "approved")
    assert ok
    row = tag_repo.get(eid)
    assert row["review_status"] == "approved"
    assert row["reviewed_at"] is not None


def test_tagging_event_duplicate_ignored(repos):
    note_repo, tag_repo = repos
    note_repo.upsert("n3", "folder", "f1", "2026-01-01T00:00:00+00:00", "/n3.md")
    tag_repo.insert("n3", "python", agent="ai")
    tag_repo.insert("n3", "python", agent="ai")  # duplicate — should be ignored
    events = tag_repo.list_by_note("n3")
    assert len(events) == 1


def test_pending_count(repos):
    note_repo, tag_repo = repos
    note_repo.upsert("n4", "memos", "m4", "2026-01-01T00:00:00+00:00", "/n4.md")
    tag_repo.insert("n4", "a", agent="ai")
    tag_repo.insert("n4", "b", agent="ai")
    assert tag_repo.count_pending() == 2
    events = tag_repo.list_by_note("n4")
    tag_repo.update_status(events[0]["id"], "approved")
    assert tag_repo.count_pending() == 1


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
