# [DEF:backend.src.models.mapping:Module]
#
# @TIER:      STANDARD
# @SEMANTICS: database, mapping, environment, migration, sqlalchemy, sqlite
# @PURPOSE:   Defines the database schema for environment metadata and database mappings using SQLAlchemy.
# @LAYER:     Domain
# @RELATION:  DEPENDS_ON -> sqlalchemy
#
# @INVARIANT: All primary keys are UUID strings.
# @CONSTRAINT: source_env_id and target_env_id must be valid environment IDs.

# [SECTION: IMPORTS]
from sqlalchemy import Column, String, Boolean, DateTime, ForeignKey, Enum as SQLEnum
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import func
import uuid
import enum
# [/SECTION]

Base = declarative_base()

# [DEF:ResourceType:Class]
# @TIER: TRIVIAL
# @PURPOSE: Enumeration of possible Superset resource types for ID mapping.
class ResourceType(str, enum.Enum):
    CHART = "chart"
    DATASET = "dataset"
    DASHBOARD = "dashboard"
# [/DEF:ResourceType:Class]


# [DEF:MigrationStatus:Class]
# @TIER: TRIVIAL
# @PURPOSE: Enumeration of possible migration job statuses.
class MigrationStatus(enum.Enum):
    PENDING = "PENDING"
    RUNNING = "RUNNING"
    COMPLETED = "COMPLETED"
    FAILED = "FAILED"
    AWAITING_MAPPING = "AWAITING_MAPPING"
# [/DEF:MigrationStatus:Class]

# [DEF:Environment:Class]
# @TIER: STANDARD
# @PURPOSE: Represents a Superset instance environment.
class Environment(Base):
    __tablename__ = "environments"

    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    name = Column(String, nullable=False)
    url = Column(String, nullable=False)
    credentials_id = Column(String, nullable=False)
# [/DEF:Environment:Class]

# [DEF:DatabaseMapping:Class]
# @TIER: STANDARD
# @PURPOSE: Represents a mapping between source and target databases.
class DatabaseMapping(Base):
    __tablename__ = "database_mappings"

    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    source_env_id = Column(String, ForeignKey("environments.id"), nullable=False)
    target_env_id = Column(String, ForeignKey("environments.id"), nullable=False)
    source_db_uuid = Column(String, nullable=False)
    target_db_uuid = Column(String, nullable=False)
    source_db_name = Column(String, nullable=False)
    target_db_name = Column(String, nullable=False)
    engine = Column(String, nullable=True)
# [/DEF:DatabaseMapping:Class]

# [DEF:MigrationJob:Class]
# @TIER: TRIVIAL
# @PURPOSE: Represents a single migration execution job.
class MigrationJob(Base):
    __tablename__ = "migration_jobs"

    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    source_env_id = Column(String, ForeignKey("environments.id"), nullable=False)
    target_env_id = Column(String, ForeignKey("environments.id"), nullable=False)
    status = Column(SQLEnum(MigrationStatus), default=MigrationStatus.PENDING)
    replace_db = Column(Boolean, default=False)
    created_at = Column(DateTime(timezone=True), server_default=func.now())
# [/DEF:MigrationJob:Class]

# [DEF:ResourceMapping:Class]
# @TIER: STANDARD
# @PURPOSE: Maps a universal UUID for a resource to its actual ID on a specific environment.
# @TEST_DATA: resource_mapping_record -> {'environment_id': 'prod-env-1', 'resource_type': 'chart', 'uuid': '123e4567-e89b-12d3-a456-426614174000', 'remote_integer_id': '42'}
class ResourceMapping(Base):
    __tablename__ = "resource_mappings"

    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    environment_id = Column(String, ForeignKey("environments.id"), nullable=False)
    resource_type = Column(SQLEnum(ResourceType), nullable=False)
    uuid = Column(String, nullable=False)
    remote_integer_id = Column(String, nullable=False)  # Stored as string to handle potentially large or composite IDs safely, though Superset usually uses integers.
    resource_name = Column(String, nullable=True) # Used for UI display
    last_synced_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
# [/DEF:ResourceMapping:Class]

# [/DEF:backend.src.models.mapping:Module]

