"""Tests for Correction Memory feature."""

import pytest

from locidb.core.db import LociDB


@pytest.fixture
def db(tmp_path):
    loci = LociDB(path=tmp_path / "test.loci")
    yield loci
    loci.close()


class TestCorrections:
    def test_correct_creates_new_node(self, db):
        old = db.memorize("We use PostgreSQL for the database", entities=["database"])
        new = db.correct(old.id, "We switched to SQLite for the database", entities=["database"])
        assert new.memory_type == "correction"
        assert new.content == "We switched to SQLite for the database"

    def test_correct_soft_deletes_old(self, db):
        old = db.memorize("Framework is Django", entities=["framework"])
        db.correct(old.id, "Framework is FastAPI", entities=["framework"])
        old_node = db.get(old.id)
        assert old_node.deleted_at is not None

    def test_correct_creates_edge(self, db):
        old = db.memorize("We deploy on AWS", entities=["cloud"])
        new = db.correct(old.id, "We deploy on GCP", entities=["cloud"])
        edges = db._store.get_edges(new.id, direction="outgoing")
        corrects_edges = [e for e in edges if e.relationship_type == "corrects"]
        assert len(corrects_edges) == 1
        assert corrects_edges[0].target_id == old.id

    def test_get_corrections_returns_only_corrections(self, db):
        db.memorize("Normal memory", entities=["test"])
        old = db.memorize("Old fact", entities=["test"])
        db.correct(old.id, "Corrected fact", entities=["test"])
        corrections = db.get_corrections()
        assert len(corrections) == 1
        assert corrections[0].content == "Corrected fact"

    def test_memorize_with_type_parameter(self, db):
        node = db.memorize("I prefer dark mode", entities=["preferences"], type="preference")
        assert node.memory_type == "preference"

    def test_memorize_with_resolve_parameter(self, db):
        old = db.memorize("API uses REST", entities=["api"])
        new = db.memorize("API uses GraphQL", entities=["api"], type="correction", resolve=old.id)
        assert new.memory_type == "correction"
        old_node = db.get(old.id)
        assert old_node.deleted_at is not None


class TestSoftDelete:
    def test_forget_is_soft_by_default(self, db):
        node = db.memorize("Temporary info", entities=["temp"])
        db.forget(node.id)
        retrieved = db.get(node.id)
        assert retrieved is not None
        assert retrieved.deleted_at is not None

    def test_forget_hard_deletes(self, db):
        node = db.memorize("Permanent delete", entities=["temp"])
        db.forget(node.id, hard=True)
        assert db.get(node.id) is None

    def test_soft_deleted_excluded_from_recall(self, db):
        node = db.memorize("Secret info about routing", entities=["routing"])
        db.forget(node.id)
        results = db.recall("routing info")
        node_ids = [r["node"].id for r in results]
        assert node.id not in node_ids
