from pathlib import Path
from typing import Optional

from pydantic import AliasChoices, AliasPath, Field
from pydantic_settings import SettingsConfigDict

from prefect.settings.base import PrefectBaseSettings
from prefect.types import LogLevel

from .api import ServerAPISettings
from .database import ServerDatabaseSettings
from .deployments import ServerDeploymentsSettings
from .ephemeral import ServerEphemeralSettings
from .events import ServerEventsSettings
from .flow_run_graph import ServerFlowRunGraphSettings
from .services import ServerServicesSettings
from .tasks import ServerTasksSettings
from .ui import ServerUISettings


class ServerSettings(PrefectBaseSettings):
    """
    Settings for controlling server behavior
    """

    model_config = SettingsConfigDict(
        env_prefix="PREFECT_SERVER_", env_file=".env", extra="ignore"
    )

    logging_level: LogLevel = Field(
        default="WARNING",
        description="The default logging level for the Prefect API server.",
        validation_alias=AliasChoices(
            AliasPath("logging_level"),
            "prefect_server_logging_level",
            "prefect_logging_server_level",
        ),
    )

    analytics_enabled: bool = Field(
        default=True,
        description="""
        When enabled, Prefect sends anonymous data (e.g. count of flow runs, package version)
        on server startup to help us improve our product.
        """,
    )

    metrics_enabled: bool = Field(
        default=False,
        description="Whether or not to enable Prometheus metrics in the API.",
        validation_alias=AliasChoices(
            AliasPath("metrics_enabled"),
            "prefect_server_metrics_enabled",
            "prefect_api_enable_metrics",
        ),
    )

    log_retryable_errors: bool = Field(
        default=False,
        description="If `True`, log retryable errors in the API and it's services.",
        validation_alias=AliasChoices(
            AliasPath("log_retryable_errors"),
            "prefect_server_log_retryable_errors",
            "prefect_api_log_retryable_errors",
        ),
    )

    register_blocks_on_start: bool = Field(
        default=True,
        description="If set, any block types that have been imported will be registered with the backend on application startup. If not set, block types must be manually registered.",
        validation_alias=AliasChoices(
            AliasPath("register_blocks_on_start"),
            "prefect_server_register_blocks_on_start",
            "prefect_api_blocks_register_on_start",
        ),
    )

    memoize_block_auto_registration: bool = Field(
        default=True,
        description="Controls whether or not block auto-registration on start",
        validation_alias=AliasChoices(
            AliasPath("memoize_block_auto_registration"),
            "prefect_server_memoize_block_auto_registration",
            "prefect_memoize_block_auto_registration",
        ),
    )

    memo_store_path: Optional[Path] = Field(
        default=None,
        description="The path to the memo store file.",
        validation_alias=AliasChoices(
            AliasPath("memo_store_path"),
            "prefect_server_memo_store_path",
            "prefect_memo_store_path",
        ),
    )

    deployment_schedule_max_scheduled_runs: int = Field(
        default=50,
        description="The maximum number of scheduled runs to create for a deployment.",
        validation_alias=AliasChoices(
            AliasPath("deployment_schedule_max_scheduled_runs"),
            "prefect_server_deployment_schedule_max_scheduled_runs",
            "prefect_deployment_schedule_max_scheduled_runs",
        ),
    )

    api: ServerAPISettings = Field(
        default_factory=ServerAPISettings,
        description="Settings for controlling API server behavior",
    )
    database: ServerDatabaseSettings = Field(
        default_factory=ServerDatabaseSettings,
        description="Settings for controlling server database behavior",
    )
    deployments: ServerDeploymentsSettings = Field(
        default_factory=ServerDeploymentsSettings,
        description="Settings for controlling server deployments behavior",
    )
    ephemeral: ServerEphemeralSettings = Field(
        default_factory=ServerEphemeralSettings,
        description="Settings for controlling ephemeral server behavior",
    )
    events: ServerEventsSettings = Field(
        default_factory=ServerEventsSettings,
        description="Settings for controlling server events behavior",
    )
    flow_run_graph: ServerFlowRunGraphSettings = Field(
        default_factory=ServerFlowRunGraphSettings,
        description="Settings for controlling flow run graph behavior",
    )
    services: ServerServicesSettings = Field(
        default_factory=ServerServicesSettings,
        description="Settings for controlling server services behavior",
    )
    tasks: ServerTasksSettings = Field(
        default_factory=ServerTasksSettings,
        description="Settings for controlling server tasks behavior",
    )
    ui: ServerUISettings = Field(
        default_factory=ServerUISettings,
        description="Settings for controlling server UI behavior",
    )
