from os import environ as env

from uipath._utils.constants import ENV_JOB_ID, ENV_JOB_KEY, ENV_ROBOT_KEY


def _get_action_id_from_context() -> str | None:
    """Get action_id from evaluation context if available."""
    try:
        # Import here to avoid circular dependency
        from uipath._cli._evals.mocks.mocks import eval_set_run_id_context

        return eval_set_run_id_context.get()
    except (ImportError, LookupError):
        return None


class UiPathExecutionContext:
    """Manages the execution context for UiPath automation processes.

    The UiPathExecutionContext class handles information about the current execution environment,
    including the job instance ID and robot key. This information is essential for
    tracking and managing automation jobs in UiPath Automation Cloud.
    """

    def __init__(
        self,
        requesting_product: str | None = None,
        requesting_feature: str | None = None,
        agenthub_config: str | None = None,
        action_id: str | None = None,
    ) -> None:
        try:
            self._instance_key: str | None = env[ENV_JOB_KEY]
        except KeyError:
            self._instance_key = None

        try:
            self._instance_id: str | None = env[ENV_JOB_ID]
        except KeyError:
            self._instance_id = None

        try:
            self._robot_key: str | None = env[ENV_ROBOT_KEY]
        except KeyError:
            self._robot_key = None

        # LLM Gateway headers for product/feature identification
        self.requesting_product = requesting_product or "uipath-python-sdk"
        self.requesting_feature = requesting_feature or "llm-call"

        # AgentHub configuration header - tells AgentHub how to route/configure the request
        self.agenthub_config = agenthub_config

        # Action ID for grouping related LLM calls in observability/audit logs
        # If not provided explicitly, try to get it from eval context
        self.action_id = action_id or _get_action_id_from_context()

        super().__init__()

    @property
    def instance_id(self) -> str | None:
        """Get the current job instance ID.

        The instance ID uniquely identifies the current automation job execution
        in UiPath Automation Cloud.

        Returns:
            Optional[str]: The job instance ID.

        Raises:
            ValueError: If the instance ID is not set in the environment.
        """
        if self._instance_id is None:
            raise ValueError(f"Instance ID is not set ({ENV_JOB_ID})")

        return self._instance_id

    @property
    def instance_key(self) -> str | None:
        """Get the current job instance key.

        The instance key uniquely identifies the current automation job execution
        in UiPath Automation Cloud.
        """
        if self._instance_key is None:
            raise ValueError(f"Instance key is not set ({ENV_JOB_KEY})")

        return self._instance_key

    @property
    def robot_key(self) -> str | None:
        """Get the current robot key.

        The robot key identifies the UiPath Robot that is executing the current
        automation job.

        Returns:
            Optional[str]: The robot key.

        Raises:
            ValueError: If the robot key is not set in the environment.
        """
        if self._robot_key is None:
            raise ValueError(f"Robot key is not set ({ENV_ROBOT_KEY})")

        return self._robot_key
