"""API key repository (tenant-scoped)."""

from __future__ import annotations

import uuid
from datetime import UTC, datetime

from sqlalchemy import select
from sqlalchemy.orm import Session

from legate.db.models.api_key import ApiKey


def create(
    db: Session,
    *,
    workspace_id: uuid.UUID,
    created_by: uuid.UUID | None,
    name: str,
    prefix: str,
    hashed_key: str,
    scopes: list[str],
) -> ApiKey:
    key = ApiKey(
        workspace_id=workspace_id,
        created_by=created_by,
        name=name,
        prefix=prefix,
        hashed_key=hashed_key,
        scopes=scopes,
    )
    db.add(key)
    db.flush()
    return key


def get_active_by_hash(db: Session, hashed_key: str) -> ApiKey | None:
    return db.scalars(
        select(ApiKey).where(
            ApiKey.hashed_key == hashed_key,
            ApiKey.revoked_at.is_(None),
        )
    ).first()


def get_by_id(db: Session, *, key_id: uuid.UUID, workspace_id: uuid.UUID) -> ApiKey | None:
    return db.scalars(
        select(ApiKey).where(ApiKey.id == key_id, ApiKey.workspace_id == workspace_id)
    ).first()


def list_for_workspace(db: Session, *, workspace_id: uuid.UUID) -> list[ApiKey]:
    return list(
        db.scalars(
            select(ApiKey)
            .where(ApiKey.workspace_id == workspace_id)
            .order_by(ApiKey.created_at.asc())
        ).all()
    )


def revoke(db: Session, key: ApiKey) -> None:
    key.revoked_at = datetime.now(UTC)
    db.flush()


def touch_last_used(db: Session, key: ApiKey) -> None:
    key.last_used_at = datetime.now(UTC)
    db.flush()
