from enum import Enum
from typing import List
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
from datetime import timedelta
from importlib.metadata import version, PackageNotFoundError

try:
    acmev2_version = version("acmev2")
except PackageNotFoundError:
    acmev2_version = "dev"


class Challenges(str, Enum):
    custom = "custom"
    dns_01 = "dns-01"
    http_01 = "http-01"


class ACMESettings(BaseSettings):
    model_config = SettingsConfigDict(validate_default=False, env_prefix="ACMEV2_")

    # If this is true all new accounts will require external account bindings
    eab_required: bool = Field(
        False,
        description="Whether all accounts are required to use external account binding or not.",
    )

    # Max number of identifiers that can be passed into a new order request
    max_identifiers: int = Field(
        50,
        description="Max number of identifiers that can be passed to a new order request.",
    )

    # How long the client should wait between polling attempts. This is
    # sent as a Retry-After header
    authorization_client_delay: int = Field(
        15, description="The Retry-After header sent to ACME clients."
    )

    # The server will refuse to issue domains for any identities in this list. It
    # supports regular expressions.
    blacklisted_domains: list[str] = Field(
        [],
        description="The server will refuse to issue domains for any identifiers in this list. It supports regular expressions.",
    )

    # How long should the order and authorization objects be valid
    # for after generating?
    resource_expiration_delta: timedelta = Field(
        timedelta(hours=8),
        description="How long should the order and authorization objects be valid for after generation?",
    )

    # Default set of challenges created when an authorization is created.
    challenges_available: list[Challenges] = Field(
        [Challenges.http_01],
        description="Default set of challenges created when an authorization is created",
    )

    # The user agent the http-01 challenge validator will use when requesting the
    # challenge document from the client server.
    http_01_challenge_user_agent: str = Field(
        f"python-acmev2/{acmev2_version}",
        description="User agent the http-01 challenge validator uses when requesting the challenge document from the client server",
    )

    # Any order requests from this user agent will mask the processing state as pending
    mask_order_processing_status_ua_match: str = Field(
        "^cert-manager-clusterissuers.*",
        description="Any order requests from this user agent will mask the processing state as pending",
    )

    dns_challenge_nameservers: List[str] = Field(
        [],
        description="A list of servers in the format ip or ip:port. The DNS challenge resolver will use these nameservers. If left blank the system nameservers will be used.",
    )
