import re

from pydantic import Field, field_validator

from data_exchange_agent.config.sections.connections.cloud_storages.base import BaseCloudStorageConnectionConfig


# S3 validation patterns (defined outside class to avoid Pydantic PrivateAttr wrapping)
_BUCKET_NAME_PATTERN = re.compile(r"^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$")
_IP_PATTERN = re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
_PROFILE_NAME_PATTERN = re.compile(r"^[a-zA-Z0-9_\-]+$")
_REGION_NAME_PATTERN = re.compile(r"^[a-z0-9]+(-[a-z0-9]+)+$")


class S3ConnectionConfig(BaseCloudStorageConnectionConfig):
    """Configuration class for AWS S3 connection settings."""

    bucket_name: str = Field(..., description="S3 bucket name")
    profile_name: str = Field(..., description="AWS profile name from credentials file")
    region_name: str | None = Field(
        default=None,
        description="AWS region name (e.g., us-east-1). Optional if region is set in AWS profile.",
    )

    @field_validator("bucket_name")
    @classmethod
    def validate_bucket_name(cls, v: str) -> str:
        """Validate S3 bucket name according to AWS naming rules."""
        if not (3 <= len(v) <= 63):
            raise ValueError("Bucket name length must be between 3 and 63 characters.")

        if not _BUCKET_NAME_PATTERN.fullmatch(v):
            raise ValueError(
                "Bucket name must start and end with a lowercase letter or number,"
                " and only contain lowercase letters, numbers, dots, and hyphens."
            )

        if _IP_PATTERN.fullmatch(v):
            raise ValueError("Bucket name cannot be formatted as an IP address (e.g., 192.168.1.1).")

        if ".." in v:
            raise ValueError("Bucket name cannot contain two adjacent periods (e.g., my..bucket).")

        if ".-" in v or "-." in v:
            raise ValueError("Bucket name cannot have a dot adjacent to a hyphen (e.g., .- or -.).")

        return v

    @field_validator("profile_name")
    @classmethod
    def validate_profile_name(cls, v: str) -> str:
        """Validate AWS profile name."""
        if not _PROFILE_NAME_PATTERN.fullmatch(v):
            raise ValueError("Profile name must only contain alphanumeric characters, hyphens (-), and underscores (_).")
        return v

    @field_validator("region_name")
    @classmethod
    def validate_region_name(cls, v: str | None) -> str | None:
        """Validate AWS region name."""
        if v is None:
            return v

        if not _REGION_NAME_PATTERN.fullmatch(v):
            raise ValueError(
                "Region name must be a valid lowercase AWS region"
                " (e.g., us-east-1, ap-southeast-1, ap-southeast-1-lz-1, eusc-de-east-1)."
            )
        return v

    def __repr__(self) -> str:
        """Return string representation of S3 connection configuration."""
        return (
            f"S3ConnectionConfig("
            f"bucket_name='{self.bucket_name}', "
            f"profile_name='{self.profile_name}', "
            f"region_name='{self.region_name}')"
        )
