# #region ManifestRepositoryModule [C:3] [TYPE Module] [SEMANTICS clean-release, manifest, repository, persistence, crud]
# @BRIEF Persist and query distribution manifests.
# @LAYER Infrastructure
# @RELATION DEPENDS_ON -> DistributionManifest
# @RELATION DEPENDS_ON -> [EXT:Library:sqlalchemy]
# @RELATION DEPENDS_ON -> belief_scope


from sqlalchemy.orm import Session

from src.core.logger import belief_scope
from src.models.clean_release import DistributionManifest


# #region ManifestRepository [C:3] [TYPE Class]
# @BRIEF Encapsulates database CRUD operations for DistributionManifest entities.
# @RELATION DEPENDS_ON -> DistributionManifest
# @RELATION DEPENDS_ON -> [EXT:Library:sqlalchemy.Session]
class ManifestRepository:
    """Repository for distribution manifest persistence."""

    # region ManifestRepository.__init__ [TYPE Function]
    # @PURPOSE: Initialize repository with an active SQLAlchemy session.
    # @PRE  db is a valid SQLAlchemy Session instance.
    # @POST  Repository is ready for database operations.
    def __init__(self, db: Session):
        self.db = db
    # endregion ManifestRepository.__init__

    # region ManifestRepository.save [TYPE Function]
    # @PURPOSE: Persist a DistributionManifest to the database.
    # @PRE  manifest is a valid DistributionManifest instance with required fields populated.
    # @POST  Manifest is committed to database and refreshed with generated ID.
    # @SIDE_EFFECT  Database commit via session.commit().
    # @RELATION DEPENDS_ON -> DistributionManifest
    def save(self, manifest: DistributionManifest) -> DistributionManifest:
        with belief_scope("ManifestRepository.save"):
            self.db.add(manifest)
            self.db.commit()
            self.db.refresh(manifest)
            return manifest
    # endregion ManifestRepository.save

    # region ManifestRepository.get_by_id [TYPE Function]
    # @PURPOSE: Retrieve a single DistributionManifest by its primary key.
    # @PRE  manifest_id is a valid string identifier.
    # @POST  Returns DistributionManifest if found, None otherwise.
    # @RELATION DEPENDS_ON -> DistributionManifest
    def get_by_id(self, manifest_id: str) -> DistributionManifest | None:
        with belief_scope("ManifestRepository.get_by_id"):
            return self.db.query(DistributionManifest).filter(
                DistributionManifest.id == manifest_id
            ).first()
    # endregion ManifestRepository.get_by_id

    # region ManifestRepository.get_latest_for_candidate [TYPE Function]
    # @PURPOSE: Retrieve the most recent manifest version for a given candidate.
    # @PRE  candidate_id is a valid string identifier.
    # @POST  Returns the highest manifest_version manifest for the candidate, or None.
    # @RELATION DEPENDS_ON -> DistributionManifest
    def get_latest_for_candidate(self, candidate_id: str) -> DistributionManifest | None:
        with belief_scope("ManifestRepository.get_latest_for_candidate"):
            return (
                self.db.query(DistributionManifest)
                .filter(DistributionManifest.candidate_id == candidate_id)
                .order_by(DistributionManifest.manifest_version.desc())
                .first()
            )
    # endregion ManifestRepository.get_latest_for_candidate

    # region ManifestRepository.list_by_candidate [TYPE Function]
    # @PURPOSE: List all manifests for a specific candidate, ordered by version.
    # @PRE  candidate_id is a valid string identifier.
    # @POST  Returns a list of DistributionManifest instances (may be empty).
    # @RELATION DEPENDS_ON -> DistributionManifest
    def list_by_candidate(self, candidate_id: str) -> list[DistributionManifest]:
        with belief_scope("ManifestRepository.list_by_candidate"):
            return (
                self.db.query(DistributionManifest)
                .filter(DistributionManifest.candidate_id == candidate_id)
                .all()
            )
    # endregion ManifestRepository.list_by_candidate

# #endregion ManifestRepository

# #endregion ManifestRepositoryModule
