"""Shared constants and Pydantic request models for the documents API package.

CODE-08: Single definition of _CLOUD_PROVIDERS, UploadUrlRequest, and DocumentPatch.
These are imported by upload.py and crud.py — never duplicated.

T-05-06-01: _CLOUD_PROVIDERS is an allowlist frozenset; target_backend validated
            against it (never against user-supplied strings).
T-05-09-01: DocumentPatch fields declared explicitly — mass assignment prevented.
T-05-09-02: filename_no_path_separators validator preserved verbatim (path traversal
            defense at the API boundary — D-11 analysis: stays in Pydantic model).
"""
from __future__ import annotations

import uuid
from typing import Optional

from pydantic import BaseModel, Field, field_validator

# Valid cloud backend slugs (T-05-06-01: validated against allowlist, not user-supplied string)
_CLOUD_PROVIDERS = frozenset({"google_drive", "onedrive", "nextcloud", "webdav"})


class UploadUrlRequest(BaseModel):
    filename: str
    content_type: str


class DocumentPatch(BaseModel):
    """Pydantic model for PATCH /api/documents/{doc_id}.

    Optional fields — model_fields_set distinguishes "not provided" from "set to null".
    At least one field must be present in model_fields_set (enforced in the handler).

    T-05-09-01: explicit field declaration prevents mass assignment.
    T-05-09-02: only filename and folder_id are accepted — no other fields can be set.
    """
    filename: Optional[str] = Field(None, min_length=1, max_length=255)
    folder_id: Optional[uuid.UUID] = None

    @field_validator("filename")
    @classmethod
    def filename_no_path_separators(cls, v: Optional[str]) -> Optional[str]:
        if v is not None and ("/" in v or "\\" in v):
            raise ValueError("filename must not contain path separators")
        return v
