"""Snowflake base connection configuration classes."""

import re

from pydantic import Field, field_validator

from data_exchange_agent.config.sections.connections.cloud_storages.base import BaseCloudStorageConnectionConfig
from data_exchange_agent.config.sections.connections.cloud_storages.snowflake.authenticator_type import (
    SnowflakeAuthenticatorType,
)


# Snowflake validation patterns (defined outside class to avoid Pydantic PrivateAttr wrapping)
_SNOWFLAKE_IDENTIFIER_WITH_DOLLAR_PATTERN = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_\$]*$")
_SNOWFLAKE_IDENTIFIER_WITH_HYPHEN_PATTERN = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_\-]*$")
_SNOWFLAKE_ACCOUNT_PATTERN = re.compile(r"^[a-zA-Z0-9][a-zA-Z0-9\.\-]*[a-zA-Z0-9]$")


class SnowflakeConnectionConfig(BaseCloudStorageConnectionConfig):
    """Base configuration class for Snowflake connection settings."""

    @classmethod
    def _validate_identifier_with_dollar(cls, value: str, field_name: str) -> str:
        """
        Validate a Snowflake identifier that allows dollar signs.

        Args:
            value: The value to validate
            field_name: The name of the field being validated

        Returns:
            str: The validated value

        Raises:
            ValueError: If the value is invalid

        """
        if not _SNOWFLAKE_IDENTIFIER_WITH_DOLLAR_PATTERN.fullmatch(value):
            raise ValueError(
                f"{field_name} must start with a letter or underscore,"
                " and only contain alphanumeric characters, underscores (_), and dollar signs ($)."
            )
        return value

    @classmethod
    def _validate_identifier_with_hyphen(cls, value: str, field_name: str) -> str:
        """
        Validate a Snowflake identifier that allows hyphens.

        Args:
            value: The value to validate
            field_name: The name of the field being validated

        Returns:
            str: The validated value

        Raises:
            ValueError: If the value is invalid

        """
        if not _SNOWFLAKE_IDENTIFIER_WITH_HYPHEN_PATTERN.fullmatch(value):
            raise ValueError(
                f"{field_name} must start with a letter or underscore,"
                " and only contain alphanumeric characters, underscores (_), and hyphens (-)."
            )
        return value


class SnowflakeExtendedBaseConnectionConfig(SnowflakeConnectionConfig):
    """
    Configuration class for Snowflake connection using extended base authentication.

    This is a base class for specific authentication methods (password, external browser).
    Do not instantiate directly - use subclasses instead.

    Example:
        >>> config = SnowflakeConnectionPasswordConfig(
        ...     account="myaccount",
        ...     user="myuser",
        ...     password="secret",
        ...     role="ANALYST",
        ...     warehouse="COMPUTE_WH",
        ...     database="MYDB",
        ...     schema="PUBLIC"
        ... )

    """

    authenticator: SnowflakeAuthenticatorType = Field(..., description="Snowflake authenticator type")
    account: str = Field(..., description="Snowflake account identifier")
    user: str = Field(..., description="Snowflake user")
    role: str = Field(..., description="Snowflake role name")
    warehouse: str = Field(..., description="Snowflake warehouse name")
    database: str = Field(..., description="Snowflake database name")
    schema_name: str = Field(..., alias="schema", description="Snowflake schema name")

    @field_validator("account")
    @classmethod
    def validate_account(cls, v: str) -> str:
        """Validate Snowflake account identifier."""
        if not _SNOWFLAKE_ACCOUNT_PATTERN.fullmatch(v):
            raise ValueError("Account must start with a letter or number," " and only contain letters, numbers, hyphens (-), and dots (.).")
        return v

    @field_validator("user")
    @classmethod
    def validate_user(cls, v: str) -> str:
        """Validate Snowflake user identifier."""
        return cls._validate_identifier_with_hyphen(v, "User")

    @field_validator("role")
    @classmethod
    def validate_role(cls, v: str) -> str:
        """Validate Snowflake role identifier."""
        return cls._validate_identifier_with_dollar(v, "Role")

    @field_validator("warehouse")
    @classmethod
    def validate_warehouse(cls, v: str) -> str:
        """Validate Snowflake warehouse identifier."""
        return cls._validate_identifier_with_dollar(v, "Warehouse")

    @field_validator("database")
    @classmethod
    def validate_database(cls, v: str) -> str:
        """Validate Snowflake database identifier."""
        return cls._validate_identifier_with_dollar(v, "Database")

    @field_validator("schema_name")
    @classmethod
    def validate_schema(cls, v: str) -> str:
        """Validate Snowflake schema identifier."""
        return cls._validate_identifier_with_dollar(v, "Schema")

    def _repr_fields(self) -> str:
        """Get string representation of fields (for use in __repr__)."""
        return (
            f"authenticator='{self.authenticator}', "
            f"account='{self._mask_sensitive_data(self.account)}', "
            f"user='{self.user}', "
            f"role='{self.role}', "
            f"warehouse='{self.warehouse}', "
            f"database='{self.database}', "
            f"schema='{self.schema_name}'"
        )

    def __repr__(self) -> str:
        """Return string representation of Snowflake extended base configuration."""
        class_name = self.__class__.__name__
        return f"{class_name}({self._repr_fields()})"
