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

from __future__ import annotations

import pytest

from db_test_helpers.core import Config, UnsupportedError, set_db_data, verify_db_data
from db_test_helpers.mysql import MysqlAdapter


class TestE2eBasic:
    def test_set_and_verify(self, conn, tmp_path):
        seed = tmp_path / "seed.yaml"
        seed.write_text(
            """\
users:
  - name: "Alice"
    age: 30
  - name: "Bob"
    age: 25
"""
        )
        expected = tmp_path / "expected.yaml"
        expected.write_text(
            """\
users:
  - id: "$any()"
    name: "Bob"
    age: 25
    email: null
    score: null
    created_at: null
    birth_date: null
    login_time: null
    bio: null
  - id: "$any()"
    name: "Alice"
    age: 30
    email: null
    score: null
    created_at: null
    birth_date: null
    login_time: null
    bio: null
"""
        )
        adapter = MysqlAdapter(conn)
        set_db_data(adapter, str(seed))
        verify_db_data(adapter, str(expected))

    def test_set_replaces_existing(self, conn, tmp_path):
        adapter = MysqlAdapter(conn)

        # Insert initial data
        adapter.write_record("users", "", {"name": "OldUser", "age": 99})

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

        records = adapter.read_records("users", "")
        assert len(records) == 1
        assert records[0]["name"] == "Alice"


class TestE2eChildren:
    def test_children_raises_not_implemented(self, conn, tmp_path):
        seed = tmp_path / "seed.yaml"
        seed.write_text(
            """\
users:
  - name: "Alice"
    age: 30
    __children__:
      posts:
        - title: "Hello"
          body: "World"
"""
        )
        adapter = MysqlAdapter(conn)
        with pytest.raises(UnsupportedError, match="does not support __children__"):
            set_db_data(adapter, str(seed))


class TestE2eDsl:
    def test_var_matcher(self, conn, tmp_path):
        seed = tmp_path / "seed.yaml"
        seed.write_text(
            """\
users:
  - name: "$var(user_name)"
    age: 30
"""
        )
        expected = tmp_path / "expected.yaml"
        expected.write_text(
            """\
users:
  - id: "$any()"
    name: "$var(user_name)"
    age: 30
    email: null
    score: null
    created_at: null
    birth_date: null
    login_time: null
    bio: null
"""
        )
        adapter = MysqlAdapter(conn)
        config = Config(variables={"user_name": "Alice"})
        set_db_data(adapter, str(seed), config)
        verify_db_data(adapter, str(expected), config)

    def test_matchers_in_verify(self, conn, tmp_path):
        seed = tmp_path / "seed.yaml"
        seed.write_text(
            """\
users:
  - name: "Alice"
    age: 30
"""
        )
        expected = tmp_path / "expected.yaml"
        expected.write_text(
            """\
users:
  - id: "$any()"
    name: "$eq(Alice)"
    age: "$and($gt(0),$lt(100))"
    email: null
    score: null
    created_at: null
    birth_date: null
    login_time: null
    bio: null
"""
        )
        adapter = MysqlAdapter(conn)
        set_db_data(adapter, str(seed))
        verify_db_data(adapter, str(expected))

    def test_verify_failure(self, conn, tmp_path):
        seed = tmp_path / "seed.yaml"
        seed.write_text(
            """\
users:
  - name: "Alice"
    age: 30
"""
        )
        expected = tmp_path / "expected.yaml"
        expected.write_text(
            """\
users:
  - id: "$any()"
    name: "Bob"
    age: 30
    email: null
    score: null
    created_at: null
    birth_date: null
    login_time: null
    bio: null
"""
        )
        adapter = MysqlAdapter(conn)
        set_db_data(adapter, str(seed))
        with pytest.raises(AssertionError):
            verify_db_data(adapter, str(expected))
