from __future__ import annotations

from typing import Literal

from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    # Which graph engine executes SPARQL queries.
    # - rdflib: parse TTL locally and query in-memory
    # - anzograph: query a remote AnzoGraph SPARQL endpoint (optionally LOAD on startup)
    graph_backend: Literal["rdflib", "anzograph"] = Field(default="rdflib", alias="GRAPH_BACKEND")

    ttl_path: str = Field(default="/data/o3po.ttl", alias="TTL_PATH")
    include_bnodes: bool = Field(default=False, alias="INCLUDE_BNODES")
    max_triples: int | None = Field(default=None, alias="MAX_TRIPLES")

    # Optional: Combine owl:imports into a single TTL file on backend startup.
    combine_owl_imports_on_start: bool = Field(default=False, alias="COMBINE_OWL_IMPORTS_ON_START")
    combine_entry_location: str | None = Field(default=None, alias="COMBINE_ENTRY_LOCATION")
    combine_output_location: str | None = Field(default=None, alias="COMBINE_OUTPUT_LOCATION")
    combine_output_name: str = Field(default="combined_ontology.ttl", alias="COMBINE_OUTPUT_NAME")
    combine_force: bool = Field(default=False, alias="COMBINE_FORCE")

    # AnzoGraph / SPARQL endpoint configuration
    sparql_host: str = Field(default="http://anzograph:8080", alias="SPARQL_HOST")
    # If not set, the backend uses `${SPARQL_HOST}/sparql`.
    sparql_endpoint: str | None = Field(default=None, alias="SPARQL_ENDPOINT")
    sparql_user: str | None = Field(default=None, alias="SPARQL_USER")
    sparql_pass: str | None = Field(default=None, alias="SPARQL_PASS")

    # File URI as seen by the AnzoGraph container (used with SPARQL `LOAD`).
    # Example: file:///opt/shared-files/o3po.ttl
    sparql_data_file: str | None = Field(default=None, alias="SPARQL_DATA_FILE")
    sparql_graph_iri: str | None = Field(default=None, alias="SPARQL_GRAPH_IRI")
    sparql_load_on_start: bool = Field(default=False, alias="SPARQL_LOAD_ON_START")
    sparql_clear_on_start: bool = Field(default=False, alias="SPARQL_CLEAR_ON_START")

    sparql_timeout_s: float = Field(default=300.0, alias="SPARQL_TIMEOUT_S")
    sparql_ready_retries: int = Field(default=30, alias="SPARQL_READY_RETRIES")
    sparql_ready_delay_s: float = Field(default=4.0, alias="SPARQL_READY_DELAY_S")
    sparql_ready_timeout_s: float = Field(default=10.0, alias="SPARQL_READY_TIMEOUT_S")

    # Comma-separated, or "*" (default).
    cors_origins: str = Field(default="*", alias="CORS_ORIGINS")

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

    def cors_origin_list(self) -> list[str]:
        if self.cors_origins.strip() == "*":
            return ["*"]
        return [o.strip() for o in self.cors_origins.split(",") if o.strip()]

    def effective_sparql_endpoint(self) -> str:
        if self.sparql_endpoint and self.sparql_endpoint.strip():
            return self.sparql_endpoint.strip()
        return self.sparql_host.rstrip("/") + "/sparql"
