"""BI CLI."""

from dataclasses import dataclass
from functools import cached_property

import typer
from slices_clientlib_core.experiment import Experiment

from slices_cli_bi import err_console
from slices_cli_bi.core.context import ContextObj


@dataclass
class BIContextObj(ContextObj):
    """BI Context object."""

    infra_id: str
    cluster_id: str

    def _require_project_id(self):
        project_id = self.get_current_project_id()
        if not project_id:
            err_console.print("[bold red]No project set. Please set a project with `slices project use <name>`. :x:")
            raise typer.Exit(1)
        return project_id

    @cached_property
    def bi_flavors_api(self):
        """BI Flavors API."""
        return self.api.for_project(self._require_project_id()).bi(self.infra_id).flavor

    @cached_property
    def bi_tasks_api(self):
        """BI Tasks API."""
        return self.api.for_project(self._require_project_id()).bi(self.infra_id).task

    @cached_property
    def bi_image_api(self):
        """BI Disk Image API."""
        return self.api.for_project(self._require_project_id()).bi(self.infra_id).image

    def get_bi_resources_api_by_experiment(self, experiment: Experiment):
        """BI Resources API."""
        return self.api.for_experiment(experiment.id, self._require_project_id()).bi(self.infra_id).resources

    def get_orchestrator_api_by_experiment(self, experiment: Experiment):
        """BI Orchestrator API."""
        return self.api.for_experiment(experiment.id, self._require_project_id()).bi_orchestrator.resources


class BIContext(typer.Context):
    """Custom context for slices-cli-bi."""

    obj: BIContextObj


class WrapContextAsBIContext:
    """Helper to wrap a regular Context so it behaves as a BIContext."""

    def __init__(self, orig_context: typer.Context, ctx_obj: BIContextObj):
        self.orig_context = orig_context
        self.ctx_obj = ctx_obj

    @property
    def obj(self):
        """Return the modified context object."""
        return self.ctx_obj

    def __getattr__(self, attr):
        """Proxy all calls to the real Context."""
        return getattr(self.orig_context, attr)
