from __future__ import annotations

from typing import Any, Dict, List, Optional

from pydantic import BaseModel, ConfigDict, Field

from goodmem.models.modality import Modality
from goodmem.models.endpoint_authentication import EndpointAuthentication
from goodmem.models.llm_capabilities import LLMCapabilities
from goodmem.models.llm_sampling_params import LLMSamplingParams


class LLMUpdateRequest(BaseModel):
    """Request body for updating an existing LLM. All fields are optional - only specified fields will be updated."""

    model_config = ConfigDict(populate_by_name=True, protected_namespaces=(), extra='forbid')

    display_name: Optional[str] = Field(default=None, description='Update display name', alias="displayName")
    description: Optional[str] = Field(default=None, description='Update description')
    endpoint_url: Optional[str] = Field(default=None, description='Update endpoint base URL (OpenAI-compatible base, typically ends with /v1)', alias="endpointUrl")
    api_path: Optional[str] = Field(default=None, description='Update API path', alias="apiPath")
    model_identifier: Optional[str] = Field(default=None, description='Update model identifier (cannot be empty)', alias="modelIdentifier")
    supported_modalities: Optional[list[Modality]] = Field(default=None, description='Update supported modalities (if array contains ≥1 elements, replaces stored set; if empty or omitted, no change)', alias="supportedModalities")
    credentials: Optional[EndpointAuthentication] = Field(default=None, description='Update credentials')
    version: Optional[str] = Field(default=None, description='Update version information')
    monitoring_endpoint: Optional[str] = Field(default=None, description='Update monitoring endpoint URL', alias="monitoringEndpoint")
    capabilities: Optional[LLMCapabilities] = Field(default=None, description='Update LLM capabilities (replaces entire capability set; clients MUST send all flags)')
    default_sampling_params: Optional[LLMSamplingParams] = Field(default=None, description='Update default sampling parameters', alias="defaultSamplingParams")
    max_context_length: Optional[int] = Field(default=None, description='Update maximum context window size in tokens', alias="maxContextLength")
    client_config: Optional[dict] = Field(default=None, description='Update provider-specific client configuration (replaces entire config; no merging)', alias="clientConfig")
    replace_labels: Optional[dict] = Field(default=None, description='Replace all existing labels with this set. Empty map clears all labels. Cannot be used with mergeLabels.', alias="replaceLabels")
    merge_labels: Optional[dict] = Field(default=None, description='Merge with existing labels: upserts with overwrite. Labels not mentioned are preserved. Cannot be used with replaceLabels.', alias="mergeLabels")

