from __future__ import annotations

from typing import Dict, Optional

from pydantic import BaseModel, Field, model_validator


class VaultConfig(BaseModel):
    url: str
    token_path: str
    mount_point: str = "secret"
    namespace: Optional[str] = None


class FileConfig(BaseModel):
    path: str


class KubernetesConfig(BaseModel):
    namespace: str
    default_secret: Optional[str] = None
    context: Optional[str] = None
    kubeconfig_path: Optional[str] = None


class SecretStoreConfig(BaseModel):
    provider: str = Field(..., pattern="^(env|vault|file|k8s)$")
    vault: Optional[VaultConfig] = None
    file: Optional[FileConfig] = None
    k8s: Optional[KubernetesConfig] = None

    @model_validator(mode="after")
    def validate_required_configs(self):
        if self.provider == "vault" and self.vault is None:
            raise ValueError("vault configuration required when provider=vault")
        if self.provider == "file" and self.file is None:
            raise ValueError("file configuration required when provider=file")
        if self.provider == "k8s" and self.k8s is None:
            raise ValueError("k8s configuration required when provider=k8s")
        return self


class ConnectionConfig(BaseModel):
    auth_type: str
    secret_mapping: Dict[str, str]


class RootConfig(BaseModel):
    secret_store: SecretStoreConfig
    connections: Dict[str, ConnectionConfig]

    def get_connection(self, name: str) -> Optional[ConnectionConfig]:
        return self.connections.get(name)
