"""Credential model — an envelope-encrypted secret for a connector (Section 5)."""

from __future__ import annotations

import uuid

from sqlalchemy import JSON, ForeignKey, String, Text, Uuid
from sqlalchemy.orm import Mapped, mapped_column

from legate.db.base import Base, TimestampMixin, UUIDPrimaryKeyMixin


class Credential(UUIDPrimaryKeyMixin, TimestampMixin, Base):
    __tablename__ = "credentials"

    workspace_id: Mapped[uuid.UUID] = mapped_column(Uuid, index=True, nullable=False)
    # One credential per connector.
    connector_id: Mapped[uuid.UUID] = mapped_column(
        Uuid, ForeignKey("connectors.id", ondelete="CASCADE"), unique=True, nullable=False
    )
    # Envelope encryption: ciphertext (secret), wrapped_dek (data key), and the
    # master key version the DEK was wrapped with. No plaintext is ever stored.
    ciphertext: Mapped[str] = mapped_column(Text, nullable=False)
    wrapped_dek: Mapped[str] = mapped_column(Text, nullable=False)
    key_version: Mapped[str] = mapped_column(String(20), nullable=False, default="1")
    # Non-secret metadata, e.g. which secret keys are present and granted scopes.
    meta: Mapped[dict] = mapped_column(JSON, nullable=False, default=dict)
    scopes: Mapped[list[str]] = mapped_column(JSON, nullable=False, default=list)

    def __repr__(self) -> str:  # pragma: no cover - debug helper
        return f"<Credential connector={self.connector_id} v={self.key_version}>"
