# #region candidate_repository [C:3] [TYPE Module] [SEMANTICS clean-release, candidate, repository, persistence, crud]
# @BRIEF Persist and query release candidates.
# @LAYER Infrastructure
# @RELATION DEPENDS_ON -> [EXT:Library:sqlalchemy]


from sqlalchemy.orm import Session

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


class CandidateRepository:
    """
    @PURPOSE: Encapsulates database operations for ReleaseCandidate.
    """
    def __init__(self, db: Session):
        self.db = db

    def save(self, candidate: ReleaseCandidate) -> ReleaseCandidate:
        """
        @PURPOSE: Persist a release candidate.
        @POST: Candidate is committed and refreshed.
        """
        with belief_scope("CandidateRepository.save"):
            # [REASON] Using merge to handle both create and update.
            # Note: In a real implementation, we might want to use a separate DB model
            # if the domain model differs significantly from the DB schema.
            # For now, we assume the domain model is compatible with SQLAlchemy Base if registered.
            self.db.add(candidate)
            self.db.commit()
            self.db.refresh(candidate)
            return candidate

    def get_by_id(self, candidate_id: str) -> ReleaseCandidate | None:
        """
        @PURPOSE: Retrieve a candidate by ID.
        """
        with belief_scope("CandidateRepository.get_by_id"):
            return self.db.query(ReleaseCandidate).filter(ReleaseCandidate.id == candidate_id).first()

    def list_all(self) -> list[ReleaseCandidate]:
        """
        @PURPOSE: List all candidates.
        """
        with belief_scope("CandidateRepository.list_all"):
            return self.db.query(ReleaseCandidate).all()

# #endregion candidate_repository
