"""E2E tests: set_db_data + verify_db_data with MongoDB."""

from __future__ import annotations

import pytest

from db_test_helpers.core import Config, set_db_data, verify_db_data
from db_test_helpers.mongo import MongoAdapter


class TestE2eBasic:
    def test_set_and_verify(self, db, tmp_path):
        seed = tmp_path / "seed.yaml"
        seed.write_text(
            """\
users:
  - __document_id__: "user-1"
    name: "Alice"
    age: 30
  - __document_id__: "user-2"
    name: "Bob"
    age: 25
"""
        )
        expected = tmp_path / "expected.yaml"
        expected.write_text(
            """\
users:
  - __document_id__: "user-2"
    name: "Bob"
    age: 25
  - __document_id__: "user-1"
    name: "Alice"
    age: 30
"""
        )
        adapter = MongoAdapter(db)
        set_db_data(adapter, str(seed))
        verify_db_data(adapter, str(expected))

    def test_set_replaces_existing(self, db, tmp_path):
        adapter = MongoAdapter(db)

        db["users"].insert_one({"_id": "old-user", "name": "OldUser"})

        seed = tmp_path / "seed.yaml"
        seed.write_text(
            """\
users:
  - __document_id__: "user-1"
    name: "Alice"
"""
        )
        set_db_data(adapter, str(seed))

        docs = list(db["users"].find())
        assert len(docs) == 1
        assert docs[0]["_id"] == "user-1"


class TestE2eChildren:
    def test_nested_children(self, db, tmp_path):
        seed = tmp_path / "seed.yaml"
        seed.write_text(
            """\
users:
  - __document_id__: "user-1"
    name: "Alice"
    __children__:
      posts:
        - __document_id__: "post-1"
          title: "Hello"
          __children__:
            comments:
              - __document_id__: "comment-1"
                body: "Nice post!"
"""
        )
        expected = tmp_path / "expected.yaml"
        expected.write_text(
            """\
users:
  - __document_id__: "user-1"
    name: "Alice"
    __children__:
      posts:
        - __document_id__: "post-1"
          title: "Hello"
          __children__:
            comments:
              - __document_id__: "comment-1"
                body: "Nice post!"
"""
        )
        adapter = MongoAdapter(db)
        set_db_data(adapter, str(seed))
        verify_db_data(adapter, str(expected))


class TestE2eDsl:
    def test_var_and_any(self, db, tmp_path):
        seed = tmp_path / "seed.yaml"
        seed.write_text(
            """\
users:
  - __document_id__: "$var(uid)"
    name: "Alice"
  - name: "Bob"
"""
        )
        expected = tmp_path / "expected.yaml"
        expected.write_text(
            """\
users:
  - __document_id__: "$var(uid)"
    name: "Alice"
  - __document_id__: "$any()"
    name: "Bob"
"""
        )
        adapter = MongoAdapter(db)
        config = Config(variables={"uid": "test-user-123"})

        set_db_data(adapter, str(seed), config)
        verify_db_data(adapter, str(expected), config)

    def test_matchers_in_verify(self, db, tmp_path):
        seed = tmp_path / "seed.yaml"
        seed.write_text(
            """\
users:
  - __document_id__: "user-1"
    name: "Alice"
    age: 30
"""
        )
        expected = tmp_path / "expected.yaml"
        expected.write_text(
            """\
users:
  - __document_id__: "$any()"
    name: "$eq(Alice)"
    age: "$and($gt(0),$lt(100))"
"""
        )
        adapter = MongoAdapter(db)
        set_db_data(adapter, str(seed))
        verify_db_data(adapter, str(expected))

    def test_verify_failure(self, db, tmp_path):
        seed = tmp_path / "seed.yaml"
        seed.write_text(
            """\
users:
  - __document_id__: "user-1"
    name: "Alice"
"""
        )
        expected = tmp_path / "expected.yaml"
        expected.write_text(
            """\
users:
  - __document_id__: "user-1"
    name: "Bob"
"""
        )
        adapter = MongoAdapter(db)
        set_db_data(adapter, str(seed))
        with pytest.raises(AssertionError):
            verify_db_data(adapter, str(expected))
