"""Tests for MongoAdapter."""

from __future__ import annotations

from db_test_helpers.mongo._adapter import MongoAdapter


class TestWriteRecord:
    def test_write_with_doc_id(self, db):
        adapter = MongoAdapter(db)
        result = adapter.write_record("users", "", {"__document_id__": "user-1", "name": "Alice"})

        assert result["__document_id__"] == "user-1"
        assert result["name"] == "Alice"

        doc = db["users"].find_one({"_id": "user-1"})
        assert doc is not None
        assert doc["name"] == "Alice"
        assert "__document_id__" not in doc

    def test_write_without_doc_id_auto_generates(self, db):
        adapter = MongoAdapter(db)
        result = adapter.write_record("users", "", {"name": "Bob"})

        assert "__document_id__" in result
        assert result["__document_id__"] is not None
        assert len(result["__document_id__"]) > 0
        assert result["name"] == "Bob"

    def test_write_with_none_doc_id_auto_generates(self, db):
        adapter = MongoAdapter(db)
        result = adapter.write_record("users", "", {"__document_id__": None, "name": "Carol"})

        assert result["__document_id__"] is not None
        assert len(result["__document_id__"]) > 0

    def test_write_with_parent_path(self, db):
        adapter = MongoAdapter(db)
        result = adapter.write_record("posts", "users/user-1", {"__document_id__": "post-1", "title": "Hello"})

        doc = db["users/user-1/posts"].find_one({"_id": "post-1"})
        assert doc is not None
        assert doc["title"] == "Hello"
        assert result["__document_id__"] == "post-1"

    def test_write_iso8601_to_datetime(self, db):
        from datetime import datetime

        adapter = MongoAdapter(db)
        adapter.write_record(
            "users", "", {"__document_id__": "user-1", "created_at": "2024-01-01T00:00:00Z"}
        )

        doc = db["users"].find_one({"_id": "user-1"})
        assert isinstance(doc["created_at"], datetime)

    def test_write_nested_iso8601_to_datetime(self, db):
        from datetime import datetime

        adapter = MongoAdapter(db)
        adapter.write_record(
            "users",
            "",
            {
                "__document_id__": "user-1",
                "meta": {"created_at": "2024-01-01T00:00:00Z"},
                "timestamps": ["2024-06-01T00:00:00Z"],
            },
        )

        doc = db["users"].find_one({"_id": "user-1"})
        assert isinstance(doc["meta"]["created_at"], datetime)
        assert isinstance(doc["timestamps"][0], datetime)

    def test_write_doc_id_not_stored_as_field(self, db):
        adapter = MongoAdapter(db)
        adapter.write_record("users", "", {"__document_id__": "user-1", "name": "Alice"})

        doc = db["users"].find_one({"_id": "user-1"})
        assert "__document_id__" not in doc


class TestReadRecords:
    def test_read_empty(self, db):
        adapter = MongoAdapter(db)
        result = adapter.read_records("users", "")
        assert result == []

    def test_read_records(self, db):
        adapter = MongoAdapter(db)
        db["users"].insert_many([
            {"_id": "user-1", "name": "Alice", "age": 30},
            {"_id": "user-2", "name": "Bob", "age": 25},
        ])

        result = adapter.read_records("users", "")
        assert len(result) == 2

        ids = {r["__document_id__"] for r in result}
        assert ids == {"user-1", "user-2"}

        for r in result:
            assert "__document_id__" in r
            assert "name" in r

    def test_read_with_parent_path(self, db):
        adapter = MongoAdapter(db)
        db["users/user-1/posts"].insert_one({"_id": "post-1", "title": "Hello"})

        result = adapter.read_records("posts", "users/user-1")
        assert len(result) == 1
        assert result[0]["__document_id__"] == "post-1"
        assert result[0]["title"] == "Hello"

    def test_read_datetime_to_iso8601(self, db):
        from datetime import UTC, datetime

        adapter = MongoAdapter(db)
        db["users"].insert_one({"_id": "user-1", "created_at": datetime(2024, 1, 1, tzinfo=UTC)})

        result = adapter.read_records("users", "")
        assert isinstance(result[0]["created_at"], str)
        assert result[0]["created_at"] == "2024-01-01T00:00:00Z"

    def test_read_datetime_roundtrip(self, db):
        """write with ISO 8601 Z -> read back as same Z format"""
        adapter = MongoAdapter(db)
        adapter.write_record("users", "", {"__document_id__": "u1", "ts": "2024-06-15T12:30:00Z"})

        result = adapter.read_records("users", "")
        assert result[0]["ts"] == "2024-06-15T12:30:00Z"

    def test_nested_datetime_conversion(self, db):
        from datetime import UTC, datetime

        adapter = MongoAdapter(db)
        db["users"].insert_one({
            "_id": "user-1",
            "meta": {"created_at": datetime(2024, 1, 1, tzinfo=UTC)},
            "timestamps": [datetime(2024, 6, 1, tzinfo=UTC)],
        })

        result = adapter.read_records("users", "")
        assert result[0]["meta"]["created_at"] == "2024-01-01T00:00:00Z"
        assert result[0]["timestamps"][0] == "2024-06-01T00:00:00Z"


class TestClearGroup:
    def test_clear_group(self, db):
        adapter = MongoAdapter(db)
        db["users"].insert_many([
            {"_id": "user-1", "name": "Alice"},
            {"_id": "user-2", "name": "Bob"},
        ])

        adapter.clear_group("users", "")
        assert db["users"].count_documents({}) == 0

    def test_clear_group_with_parent_path(self, db):
        adapter = MongoAdapter(db)
        db["users/user-1/posts"].insert_one({"_id": "post-1", "title": "Hello"})

        adapter.clear_group("posts", "users/user-1")
        assert db["users/user-1/posts"].count_documents({}) == 0


class TestBuildChildPath:
    def test_root_level(self):
        adapter = MongoAdapter(None)
        result = adapter.build_child_path("", "users", {"__document_id__": "user-1", "name": "Alice"})
        assert result == "users/user-1"

    def test_nested(self):
        adapter = MongoAdapter(None)
        result = adapter.build_child_path("users/user-1", "posts", {"__document_id__": "post-1", "title": "Hello"})
        assert result == "users/user-1/posts/post-1"
