from typing import Callable, Optional

from edgegap_scheduling import Scheduler
from edgegap_settings import ProjectBaseSettings, SettingsFactory
from fastapi import APIRouter
from pydantic import BaseModel, ConfigDict, Field

from ._environment import EnvironmentConfiguration
from ._logging import LoggingConfiguration
from .health.checks import CheckInterface


class ServiceConfiguration(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)
    name: str = Field(..., description="The name of the Service")
    version: str = Field(..., description="The version of the Service")
    description: str = Field(..., description="The description of the Service")
    routers: list[APIRouter] = Field([], description="The FastAPI routers")
    root_dir: str = Field(..., description="The Root Directory of the Service")
    static_dir: str = Field(default="static", description="The Static Directory of the Service")
    html_index_path: str | None = Field(default=None, description="The full path to the html index file")
    checks: list[type(CheckInterface)] = Field([], description="The list of Checks to run on the Service")
    depend: Optional[Callable] = Field(default=None, description="The Base Depend Attribute for DB Session")
    port: int = Field(default=8000, description="The Port of the Service")
    host: str = Field(default="0.0.0.0", description="The Host of the Service")
    workers: int = Field(default=1, description="Numbers of Workers, (if you use the scheduler, keep to 1)")
    timeout: int = Field(default=300, description="Default Timeout for Connection")
    worker_class: str = Field(default="uvicorn.workers.UvicornWorker", description="The worker class for ASGI")
    scheduler: Scheduler | None = Field(default=None, description="A Scheduler to start at boot")
    startup_functions: list[Callable] = Field(default=[], description="All function will be called on startup")
    env_config: EnvironmentConfiguration = Field(
        default=SettingsFactory.from_settings(EnvironmentConfiguration),
        description="The Configuration coming from the Environment Variables"
    )
    log_config: LoggingConfiguration = Field(
        default=LoggingConfiguration(),
        description="The Configuration for the Logging, will be passed as DictConfig to Python logging system"
    )
    settings: ProjectBaseSettings | None = Field(
        default=None,
        description="Project Specific Settings to hold in the Service"
    )
    tags_definition: list[dict] = Field(
        default=[],
        description="See https://fastapi.tiangolo.com/tutorial/metadata/#use-your-tags for details"
    )
