"""Database Models are defined here."""

from datetime import UTC, datetime

from sqlalchemy import (
    JSON,
    Boolean,
    DateTime,
    Float,
    ForeignKey,
    Integer,
    String,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship

from pem.db.database import Base


class Job(Base):
    """Represents a job that can be executed."""

    __tablename__ = "jobs"

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    name: Mapped[str] = mapped_column(String, unique=True, nullable=False, index=True)
    job_type: Mapped[str] = mapped_column(String, nullable=False)
    path: Mapped[str] = mapped_column(String, nullable=False)
    dependencies: Mapped[list[str] | None] = mapped_column(JSON, nullable=True)
    python_version: Mapped[float | None] = mapped_column(Float, nullable=True)
    is_enabled: Mapped[bool] = mapped_column(Boolean, default=True)

    runs: Mapped[list["ExecutionRun"]] = relationship(
        "ExecutionRun",
        back_populates="job",
        cascade="all, delete-orphan",
    )


class ExecutionRun(Base):
    """Represents a single execution of a job."""

    __tablename__ = "execution_runs"

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    job_id: Mapped[int] = mapped_column(Integer, ForeignKey("jobs.id"), nullable=False)
    start_time: Mapped[datetime] = mapped_column(DateTime, default=datetime.now(UTC))
    end_time: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
    status: Mapped[str] = mapped_column(String, nullable=False)
    exit_code: Mapped[int | None] = mapped_column(Integer, nullable=True)
    log_path: Mapped[str | None] = mapped_column(String, nullable=True)

    job: Mapped["Job"] = relationship(
        "Job",
        back_populates="runs",
    )
