from __future__ import annotations

import json
import os
from dataclasses import dataclass

from cognite.client.data_classes.data_modeling import DataModelId


@dataclass
class Config:
    client_id: str
    tenant_id: str
    cluster: str
    project: str
    client_secret: str
    data_models: list[DataModelId]
    instance_spaces: list[str]
    token_url: str | None = None

    @classmethod
    def from_env(cls) -> Config:
        """Parse configuration from environment variables.

        Required env vars:
            CDF_CLIENT_ID, CDF_TENANT_ID, CDF_CLUSTER, CDF_PROJECT,
            CDF_CLIENT_SECRET, CDF_DATA_MODELS, CDF_INSTANCE_SPACES

        Optional env vars:
            CDF_TOKEN_URL - Override the OAuth token URL (defaults to Azure AD)
        """
        missing = []
        for var in [
            "CDF_CLIENT_ID",
            "CDF_TENANT_ID",
            "CDF_CLUSTER",
            "CDF_PROJECT",
            "CDF_CLIENT_SECRET",
            "CDF_DATA_MODELS",
            "CDF_INSTANCE_SPACES",
        ]:
            if not os.environ.get(var):
                missing.append(var)

        if missing:
            raise ValueError(
                f"Missing required environment variables: {', '.join(missing)}"
            )

        # Parse CDF_DATA_MODELS JSON into DataModelId instances
        raw_models = json.loads(os.environ["CDF_DATA_MODELS"])
        data_models = []
        for m in raw_models:
            data_models.append(
                DataModelId(
                    space=m["space"],
                    external_id=m["externalId"],
                    version=m.get("version"),
                )
            )

        instance_spaces = json.loads(os.environ["CDF_INSTANCE_SPACES"])

        return cls(
            client_id=os.environ["CDF_CLIENT_ID"],
            tenant_id=os.environ["CDF_TENANT_ID"],
            cluster=os.environ["CDF_CLUSTER"],
            project=os.environ["CDF_PROJECT"],
            client_secret=os.environ["CDF_CLIENT_SECRET"],
            data_models=data_models,
            instance_spaces=instance_spaces,
            token_url=os.environ.get("CDF_TOKEN_URL") or None,
        )
