"""Tests for SimHash deduplication."""

import sqlite3

import pytest

from neo_cortex.dedup import DedupStore, hamming_distance, simhash


def _make_conn(tmp_path, name="dedup.db"):
    return sqlite3.connect(str(tmp_path / name), check_same_thread=False)


class TestSimHash:
    def test_simhash_deterministic(self):
        """Same text → same hash."""
        h1 = simhash("the quick brown fox")
        h2 = simhash("the quick brown fox")
        assert h1 == h2

    def test_simhash_returns_int(self):
        h = simhash("some text here")
        assert isinstance(h, int)

    def test_simhash_similar_texts_close(self):
        """Similar texts → low Hamming distance (< 10 of 64 bits)."""
        h1 = simhash("fix encoding bug in process stdin")
        h2 = simhash("fix encoding bug in process stdout")
        assert hamming_distance(h1, h2) <= 10

    def test_simhash_different_texts_far(self):
        """Different texts → high Hamming distance."""
        h1 = simhash("fix encoding bug in stdin")
        h2 = simhash("deploy neo-cortex to production server")
        assert hamming_distance(h1, h2) > 10

    def test_simhash_empty_string(self):
        h = simhash("")
        assert isinstance(h, int)


class TestHammingDistance:
    def test_zero_for_identical(self):
        assert hamming_distance(0xABCD, 0xABCD) == 0

    def test_known_value(self):
        assert hamming_distance(0b1010, 0b1000) == 1

    def test_all_bits_different(self):
        assert hamming_distance(0x0, 0xFFFFFFFFFFFFFFFF) == 64


class TestDedupStore:
    def test_is_duplicate_false_for_new(self, tmp_path):
        """First memory → never duplicate."""
        store = DedupStore(_make_conn(tmp_path))
        assert store.is_duplicate("some new text") is False

    def test_is_duplicate_true_for_same(self, tmp_path):
        """Identical text → duplicate."""
        store = DedupStore(_make_conn(tmp_path))
        store.add("fix the encoding bug")
        assert store.is_duplicate("fix the encoding bug") is True

    def test_is_duplicate_true_for_similar(self, tmp_path):
        """Near-identical text (Hamming ≤ threshold) → duplicate."""
        store = DedupStore(_make_conn(tmp_path))
        store.add("fix encoding bug in process stdin")
        assert store.is_duplicate("fix encoding bug in process stdout") is True

    def test_is_duplicate_false_for_different(self, tmp_path):
        """Different text → not duplicate."""
        store = DedupStore(_make_conn(tmp_path))
        store.add("fix encoding bug in process stdin")
        assert store.is_duplicate("deploy neo-cortex to pypi server now") is False

    def test_persistence(self, tmp_path):
        """Hashes survive restart (same DB file)."""
        db = str(tmp_path / "dedup.db")
        conn1 = sqlite3.connect(db, check_same_thread=False)
        store1 = DedupStore(conn1)
        store1.add("some persistent text")
        conn1.close()
        conn2 = sqlite3.connect(db, check_same_thread=False)
        store2 = DedupStore(conn2)
        assert store2.is_duplicate("some persistent text") is True

    def test_add_returns_hash(self, tmp_path):
        store = DedupStore(_make_conn(tmp_path))
        h = store.add("some text")
        assert isinstance(h, int)
