"""Table metadata discovery for replay validation.

Provides a minimal ABC for inspecting table structure at runtime:
primary-key columns, estimated row count, and column metadata.
Dialect-specific implementations will be added as platform support
matures.
"""

from __future__ import annotations

from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import Any


@dataclass
class ColumnInfo:
    """Lightweight column descriptor."""

    name: str
    data_type: str
    is_nullable: bool = True
    ordinal_position: int = 0


@dataclass
class TableMeta:
    """Aggregated metadata for a single table."""

    schema_name: str
    table_name: str
    columns: list[ColumnInfo] = field(default_factory=list)
    primary_key_columns: list[str] = field(default_factory=list)
    estimated_row_count: int = 0


class TableInspector(ABC):
    """Abstract base for dialect-specific table metadata discovery."""

    @abstractmethod
    def get_primary_key(
        self,
        connection: Any,
        schema: str,
        table: str,
    ) -> list[str]:
        """Return ordered list of PK column names (empty if none)."""

    @abstractmethod
    def estimated_row_count(
        self,
        connection: Any,
        schema: str,
        table: str,
    ) -> int:
        """Return an approximate row count (used for strategy selection)."""

    @abstractmethod
    def get_columns(
        self,
        connection: Any,
        schema: str,
        table: str,
    ) -> list[ColumnInfo]:
        """Return column metadata for *table*."""

    def inspect(
        self,
        connection: Any,
        schema: str,
        table: str,
    ) -> TableMeta:
        """Convenience: build a full :class:`TableMeta` in one call."""
        return TableMeta(
            schema_name=schema,
            table_name=table,
            columns=self.get_columns(connection, schema, table),
            primary_key_columns=self.get_primary_key(connection, schema, table),
            estimated_row_count=self.estimated_row_count(connection, schema, table),
        )
