"""Configuration management for mssql-mcp using pydantic-settings."""

from pydantic import Field, computed_field
from pydantic_settings import BaseSettings


class MSSQLConfig(BaseSettings):
    """Configuration for MS SQL MCP Server, loaded from environment variables.

    Required environment variables:
        MSSQL_HOST: SQL Server hostname or IP address
        MSSQL_USER: Username for authentication
        MSSQL_PASSWORD: Password for authentication
        MSSQL_DATABASE: Database name to connect to

    Optional environment variables:
        MSSQL_PORT: Server port (default: 1433)
        MSSQL_TIMEOUT: Connection timeout in seconds
        MSSQL_READ_ONLY: Disable write operations
        MSSQL_MAX_ROWS: Maximum query results
        MSSQL_QUERY_TIMEOUT: Query execution timeout
        MSSQL_BLOCKED_COMMANDS: Comma-separated list of blocked SQL commands
    """

    # Required connection settings
    host: str = Field(
        ...,
        alias="MSSQL_HOST",
        description="SQL Server hostname or IP address",
    )
    user: str = Field(
        ...,
        alias="MSSQL_USER",
        description="Username for authentication",
    )
    password: str = Field(
        ...,
        alias="MSSQL_PASSWORD",
        description="Password for authentication",
    )
    database: str = Field(
        ...,
        alias="MSSQL_DATABASE",
        description="Database name to connect to",
    )

    # Optional connection settings
    port: int = Field(
        default=1433,
        alias="MSSQL_PORT",
        description="SQL Server port",
    )
    timeout: int = Field(
        default=30,
        alias="MSSQL_TIMEOUT",
        description="Connection timeout in seconds",
    )

    # Safety settings
    read_only: bool = Field(
        default=False,
        alias="MSSQL_READ_ONLY",
        description="Disable write operations (INSERT, UPDATE, DELETE)",
    )
    max_rows: int = Field(
        default=1000,
        alias="MSSQL_MAX_ROWS",
        description="Maximum rows returned by queries",
    )
    query_timeout: int = Field(
        default=60,
        alias="MSSQL_QUERY_TIMEOUT",
        description="Maximum seconds for a query to execute before timeout",
    )
    # Store as string to avoid pydantic-settings JSON parsing issues
    blocked_commands_str: str = Field(
        default="DROP,TRUNCATE,ALTER,CREATE,GRANT,REVOKE,DENY,BACKUP,RESTORE,KILL,SHUTDOWN,RECONFIGURE",
        alias="MSSQL_BLOCKED_COMMANDS",
        description="Comma-separated list of blocked SQL commands",
    )
    allowed_schemas_str: str = Field(
        default="",
        alias="MSSQL_ALLOWED_SCHEMAS",
        description="Comma-separated list of allowed schemas (empty = all)",
    )
    blocked_databases_str: str = Field(
        default="",
        alias="MSSQL_BLOCKED_DATABASES",
        description="Comma-separated list of blocked database names",
    )

    # HTTP Server settings (for centralized deployment)
    http_host: str = Field(
        default="127.0.0.1",
        alias="MSSQL_HTTP_HOST",
        description="Host to bind HTTP server to",
    )
    http_port: int = Field(
        default=8080,
        alias="MSSQL_HTTP_PORT",
        description="Port for HTTP server",
    )
    http_cors_origins_str: str = Field(
        default="*",
        alias="MSSQL_HTTP_CORS_ORIGINS",
        description="Comma-separated list of allowed CORS origins, or * for all",
    )

    # OAuth/Authentication settings (for Claude.ai Integrations)
    auth_enabled: bool = Field(
        default=False,
        alias="MSSQL_AUTH_ENABLED",
        description="Enable OAuth authentication for Streamable HTTP endpoint",
    )
    auth_issuer_url: str | None = Field(
        default=None,
        alias="MSSQL_AUTH_ISSUER_URL",
        description="OAuth issuer URL (this server's public URL)",
    )

    # Token settings
    token_expiry_seconds: int = Field(
        default=3600,
        alias="MSSQL_TOKEN_EXPIRY_SECONDS",
        description="Access token expiry time in seconds",
    )
    refresh_token_expiry_seconds: int = Field(
        default=2592000,  # 30 days
        alias="MSSQL_REFRESH_TOKEN_EXPIRY_SECONDS",
        description="Refresh token expiry time in seconds",
    )

    # Identity Provider settings (for OAuth with external IdP)
    idp_provider: str = Field(
        default="duo",
        alias="MSSQL_IDP_PROVIDER",
        description="Identity provider type: 'duo', 'auth0', or 'oidc'",
    )
    idp_discovery_url: str | None = Field(
        default=None,
        alias="MSSQL_IDP_DISCOVERY_URL",
        description="OIDC discovery URL (.well-known/openid-configuration)",
    )
    idp_client_id: str | None = Field(
        default=None,
        alias="MSSQL_IDP_CLIENT_ID",
        description="OAuth client ID for the identity provider",
    )
    idp_client_secret: str | None = Field(
        default=None,
        alias="MSSQL_IDP_CLIENT_SECRET",
        description="OAuth client secret for the identity provider",
    )
    idp_scopes: str = Field(
        default="openid profile email groups",
        alias="MSSQL_IDP_SCOPES",
        description="Space-separated list of OAuth scopes to request",
    )
    duo_api_host: str | None = Field(
        default=None,
        alias="MSSQL_DUO_API_HOST",
        description="Duo API hostname (e.g., api-XXXXXXXX.duosecurity.com)",
    )

    # Audit logging settings
    audit_enabled: bool = Field(
        default=False,
        alias="MSSQL_AUDIT_ENABLED",
        description="Enable audit logging of all MCP tool calls",
    )
    audit_log_file: str = Field(
        default="mssql_mcp_audit.log",
        alias="MSSQL_AUDIT_LOG_FILE",
        description="Path for audit log file",
    )

    # Connection watchdog settings
    watchdog_enabled: bool = Field(
        default=True,
        alias="MSSQL_WATCHDOG_ENABLED",
        description="Enable connection health monitoring watchdog",
    )
    watchdog_interval: int = Field(
        default=30,
        alias="MSSQL_WATCHDOG_INTERVAL",
        description="Watchdog check interval in seconds",
    )
    watchdog_timeout: int = Field(
        default=10,
        alias="MSSQL_WATCHDOG_TIMEOUT",
        description="Timeout for each health check in seconds",
    )
    watchdog_max_failures: int = Field(
        default=3,
        alias="MSSQL_WATCHDOG_MAX_FAILURES",
        description="Consecutive failures before forcing reconnect",
    )

    @computed_field  # type: ignore[prop-decorator]  # pydantic pattern
    @property
    def blocked_commands(self) -> list[str]:
        """Parse comma-separated string into list of blocked commands."""
        return [cmd.strip().upper() for cmd in self.blocked_commands_str.split(",") if cmd.strip()]

    @computed_field  # type: ignore[prop-decorator]  # pydantic pattern
    @property
    def allowed_schemas(self) -> list[str]:
        """Parse comma-separated string into list of allowed schemas."""
        if not self.allowed_schemas_str.strip():
            return []
        return [schema.strip() for schema in self.allowed_schemas_str.split(",") if schema.strip()]

    @computed_field  # type: ignore[prop-decorator]  # pydantic pattern
    @property
    def blocked_databases(self) -> list[str]:
        """Parse comma-separated string into list of blocked database names."""
        if not self.blocked_databases_str.strip():
            return []
        return [db.strip().lower() for db in self.blocked_databases_str.split(",") if db.strip()]

    @computed_field  # type: ignore[prop-decorator]  # pydantic pattern
    @property
    def http_cors_origins(self) -> list[str]:
        """Parse comma-separated CORS origins into list."""
        origins = self.http_cors_origins_str.strip()
        if origins == "*":
            return ["*"]
        return [o.strip() for o in origins.split(",") if o.strip()]

    model_config = {
        "env_prefix": "",
        "case_sensitive": False,
        "populate_by_name": True,
    }
