"""tests for threetears.datasources.entities.

covers enum membership + value stability, flat-PK shape on
CapabilitySourceEntity, composite-PK shape on TableTemplateEntity, flat-PK
shape on DataSourceTableEntity / DataSourceColumnEntity /
DataSourceRelationEntity, and BaseEntity subclass invariants.
"""

from __future__ import annotations

from uuid import UUID, uuid4

from threetears.datasources.entities import (
    CapabilitySourceEntity,
    DataSourceAccessMode,
    DataSourceColumnEntity,
    DataSourceRelationEntity,
    DataSourceStatus,
    DataSourceTableEntity,
    DataSourceType,
    TableTemplateEntity,
)


class TestDataSourceTypeEnum:
    """enum carries every documented backend type with stable string values."""

    def test_members(self) -> None:
        assert {m.value for m in DataSourceType} == {
            "redshift",
            "snowflake",
            "bigquery",
            "postgres",
            "yugabyte",
            "agent_internal",
        }

    def test_str_equivalence(self) -> None:
        # StrEnum: members compare equal to their string values
        assert DataSourceType.REDSHIFT == "redshift"
        assert DataSourceType.AGENT_INTERNAL == "agent_internal"


class TestDataSourceAccessModeEnum:
    """three access-mode values; no surprises."""

    def test_members(self) -> None:
        assert {m.value for m in DataSourceAccessMode} == {"read", "write", "readwrite"}


class TestDataSourceStatusEnum:
    """lifecycle enum is two-valued; no soft-delete sentinel."""

    def test_members(self) -> None:
        assert {m.value for m in DataSourceStatus} == {"active", "disabled"}


class TestCapabilitySourceEntity:
    """flat-PK shape post-knowledge-task-08: ``primary_key_field == 'id'``.

    the v016 migration rebuilt the table PK on ``id`` alone (dropping the
    v001 composite ``(customer_id, id)`` partition PK) so a platform-shared
    source can carry ``customer_id = NULL`` (KNW-76); ``customer_id`` is
    now a plain nullable column, not the partition / addressing key.
    """

    def test_id_is_flat_primary_key(self) -> None:
        row_id = uuid4()
        entity = CapabilitySourceEntity(
            data={"customer_id": uuid4(), "id": row_id, "name": "ds"},
            is_new=True,
        )
        # scalar id property returns the row UUID
        assert entity.id == row_id
        # the addressing key is the flat ``id`` now, not the partition column
        assert entity.primary_key_field == "id"

    def test_platform_shared_source_id_with_null_customer(self) -> None:
        """a platform-shared source (customer_id NULL) addresses by id."""
        row_id = uuid4()
        entity = CapabilitySourceEntity(
            data={"customer_id": None, "id": row_id, "name": "shared"},
            is_new=True,
        )
        assert entity.id == row_id
        assert entity.customer_id is None


class TestDataSourceTableEntity:
    """flat-PK shape: ``primary_key_field == 'id'``."""

    def test_flat_pk(self) -> None:
        entity = DataSourceTableEntity(
            data={"id": uuid4(), "datasource_id": uuid4(), "schema_name": "s", "table_name": "t"},
            is_new=True,
        )
        assert entity.primary_key_field == "id"


class TestDataSourceColumnEntity:
    """flat-PK column entity carries the natural-key fields as data."""

    def test_flat_pk_and_data(self) -> None:
        column_id = uuid4()
        entity = DataSourceColumnEntity(
            data={
                "id": column_id,
                "datasource_id": uuid4(),
                "schema_name": "s",
                "table_name": "t",
                "column_name": "c",
                "data_type": "int",
                "is_nullable": False,
                "ordinal_position": 1,
            },
            is_new=True,
        )
        assert entity.primary_key_field == "id"


class TestDataSourceRelationEntity:
    """relation entities are flat-PK; cross-table metadata lives in data."""

    def test_flat_pk(self) -> None:
        entity = DataSourceRelationEntity(
            data={"id": uuid4(), "name": "r1"},
            is_new=True,
        )
        assert entity.primary_key_field == "id"


class TestTableTemplateEntity:
    """template entities carry the composite-PK ``(customer_id, id)`` shape."""

    def test_id_and_partition(self) -> None:
        template_id = uuid4()
        entity = TableTemplateEntity(
            data={"customer_id": uuid4(), "id": template_id, "name": "tpl"},
            is_new=True,
        )
        assert entity.id == template_id
        assert isinstance(entity.id, UUID)
        assert entity.primary_key_field == "customer_id"
