"""Tests for export/import sync functionality."""

import json
from pathlib import Path

from memotrail.storage.sqlite_store import SQLiteStore
from memotrail.sync.exporter import DataExporter
from memotrail.sync.importer import DataImporter
from memotrail.core.temporal import TemporalTracker


def _make_store(tmp_path: Path) -> SQLiteStore:
    tmp_path.mkdir(parents=True, exist_ok=True)
    store = SQLiteStore(db_path=tmp_path / "test.db")
    store.connect()
    TemporalTracker(store)  # Ensure fact_history table exists
    return store


class TestExporter:
    def test_export_empty_db(self, tmp_path):
        store = _make_store(tmp_path)
        exporter = DataExporter(store)
        output = tmp_path / "export.json"
        summary = exporter.export_all(output)
        assert output.exists()
        assert summary["sessions"] == 0

    def test_export_with_data(self, tmp_path):
        store = _make_store(tmp_path)
        session = store.create_session(project="proj1")
        store.add_message(session.id, "user", "Hello")
        store.add_decision(session.id, "Use Python", category="technology")
        store.save_memory("Remember this", tags=["test"])

        exporter = DataExporter(store)
        output = tmp_path / "export.json"
        summary = exporter.export_all(output)

        assert summary["sessions"] == 1
        assert summary["messages"] == 1
        assert summary["decisions"] == 1
        assert summary["memories"] == 1

        # Verify JSON structure
        data = json.loads(output.read_text())
        assert data["version"] == "1.0.0"
        assert len(data["sessions"]) == 1
        assert data["sessions"][0]["project"] == "proj1"

    def test_export_project(self, tmp_path):
        store = _make_store(tmp_path)
        s1 = store.create_session(project="proj1")
        s2 = store.create_session(project="proj2")
        store.add_message(s1.id, "user", "Proj1 msg")
        store.add_message(s2.id, "user", "Proj2 msg")

        exporter = DataExporter(store)
        output = tmp_path / "proj1_export.json"
        summary = exporter.export_project("proj1", output)

        assert summary["sessions"] == 1
        data = json.loads(output.read_text())
        assert data["project"] == "proj1"
        assert len(data["messages"]) == 1


class TestImporter:
    def test_import_basic(self, tmp_path):
        # First export
        store1 = _make_store(tmp_path / "db1")
        session = store1.create_session(project="proj1")
        store1.add_message(session.id, "user", "Hello")
        store1.add_decision(session.id, "Use Python", category="technology")
        store1.save_memory("Remember this")

        exporter = DataExporter(store1)
        export_file = tmp_path / "export.json"
        exporter.export_all(export_file)

        # Then import into a new DB
        store2 = _make_store(tmp_path / "db2")
        importer = DataImporter(store2)
        counts = importer.import_from_file(export_file)

        assert counts["sessions"] == 1
        assert counts["messages"] == 1
        assert counts["decisions"] == 1
        assert counts["memories"] == 1

    def test_import_merge_skips_duplicates(self, tmp_path):
        store = _make_store(tmp_path)
        session = store.create_session(project="proj1")
        store.add_message(session.id, "user", "Hello")

        exporter = DataExporter(store)
        export_file = tmp_path / "export.json"
        exporter.export_all(export_file)

        # Import same data again (merge mode)
        importer = DataImporter(store)
        counts = importer.import_from_file(export_file, merge=True)

        # Should not create duplicates
        assert counts["sessions"] == 0
        assert counts["messages"] == 0

    def test_import_empty_file(self, tmp_path):
        store = _make_store(tmp_path)
        export_file = tmp_path / "empty.json"
        export_file.write_text(json.dumps({
            "version": "1.0.0",
            "sessions": [],
            "messages": [],
        }))

        importer = DataImporter(store)
        counts = importer.import_from_file(export_file)
        assert all(v == 0 for v in counts.values())

    def test_roundtrip_preserves_data(self, tmp_path):
        store1 = _make_store(tmp_path / "db1")
        session = store1.create_session(project="myapp")
        store1.add_message(session.id, "user", "Build a REST API")
        store1.add_message(session.id, "assistant", "I'll use FastAPI")
        store1.add_decision(session.id, "Use FastAPI", category="technology")
        store1.save_memory("Always use type hints", tags=["convention"])

        exporter = DataExporter(store1)
        export_file = tmp_path / "roundtrip.json"
        exporter.export_all(export_file)

        store2 = _make_store(tmp_path / "db2")
        importer = DataImporter(store2)
        importer.import_from_file(export_file)

        # Verify data integrity
        sessions = store2.get_recent_sessions(limit=10)
        assert len(sessions) == 1
        assert sessions[0].project == "myapp"

        messages = store2.get_session_messages(session.id)
        assert len(messages) == 2

        decisions = store2.get_decisions()
        assert len(decisions) == 1
        assert "FastAPI" in decisions[0].decision_text


class TestCloudBackup:
    def test_encrypt_decrypt_roundtrip(self):
        from memotrail.sync.cloud import CloudBackup
        backup = CloudBackup(bucket="test", encryption_key="secret123")
        original = b"Hello, world! This is test data."
        encrypted = backup._encrypt(original)
        assert encrypted != original
        decrypted = backup._decrypt(encrypted)
        assert decrypted == original

    def test_encrypt_empty_data(self):
        from memotrail.sync.cloud import CloudBackup
        backup = CloudBackup(bucket="test", encryption_key="key")
        encrypted = backup._encrypt(b"")
        decrypted = backup._decrypt(encrypted)
        assert decrypted == b""
