from __future__ import annotations

from datetime import datetime, timezone
from fnmatch import fnmatchcase
import json
import os
import shlex
from threading import Lock
import time
from types import SimpleNamespace
from typing import Any
from urllib.parse import quote

import httpx

from src.langfuse_client import LangfuseHTTPClient, build_langfuse_client


class LangfuseControlError(RuntimeError):
    pass


_OPENAPI_CACHE_LOCK = Lock()
_OPENAPI_CACHE: dict[str, Any] = {}


def _now_iso() -> str:
    return datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")


def _as_plain(value: Any) -> Any:
    if isinstance(value, SimpleNamespace):
        return {k: _as_plain(v) for k, v in vars(value).items()}
    if isinstance(value, dict):
        return {str(k): _as_plain(v) for k, v in value.items()}
    if isinstance(value, (list, tuple)):
        return [_as_plain(v) for v in value]
    return value


def _is_sensitive_key(key: str) -> bool:
    lowered = key.lower()
    return any(token in lowered for token in ("secret", "password", "token", "api_key", "authorization"))


def _redact(value: Any) -> Any:
    if isinstance(value, dict):
        result: dict[str, Any] = {}
        for key, item in value.items():
            if _is_sensitive_key(str(key)):
                result[str(key)] = "***"
            else:
                result[str(key)] = _redact(item)
        return result
    if isinstance(value, list):
        return [_redact(item) for item in value]
    return value


def _parse_json_message(message: str) -> dict[str, Any] | None:
    text = str(message or "").strip()
    if not text:
        return None
    if text.startswith("{") and text.endswith("}"):
        try:
            payload = json.loads(text)
            return payload if isinstance(payload, dict) else None
        except Exception:
            return None
    return None


def _parse_key_value_message(message: str) -> dict[str, Any]:
    pairs: dict[str, Any] = {}
    try:
        tokens = shlex.split(message)
    except Exception:
        tokens = str(message or "").split()

    for token in tokens:
        if "=" not in token:
            continue
        key, value = token.split("=", 1)
        key = key.strip()
        value = value.strip()
        if not key:
            continue
        pairs[key] = value

    operation = str(pairs.get("op") or pairs.get("operation") or "status").strip()
    params: dict[str, Any] = {}
    for key, value in pairs.items():
        if key in {"op", "operation"}:
            continue
        params[key] = value

    return {"operation": operation, "params": params}


def parse_control_message(message: str) -> dict[str, Any]:
    parsed = _parse_json_message(message)
    if parsed is not None:
        if "operation" in parsed:
            parsed.setdefault("params", {})
            if not isinstance(parsed.get("params"), dict):
                parsed["params"] = {}
            return parsed
        # relaxed JSON schema: {"op": ..., ...params }
        op = str(parsed.get("op") or parsed.get("operation") or "status")
        params = {k: v for k, v in parsed.items() if k not in {"op", "operation"}}
        return {"operation": op, "params": params}

    return _parse_key_value_message(message)


def _env_int(name: str, default: int, *, minimum: int, maximum: int) -> int:
    raw = str(os.getenv(name, "")).strip()
    if not raw:
        return default
    try:
        value = int(raw)
    except Exception:
        return default
    return max(minimum, min(value, maximum))


def resolve_langfuse_settings() -> dict[str, Any]:
    host = str(os.getenv("LANGFUSE_BASE_URL", "")).strip()
    public_key = str(os.getenv("LANGFUSE_PUBLIC_KEY", "")).strip()
    secret_key = str(os.getenv("LANGFUSE_SECRET_KEY", "")).strip()
    environment = str(os.getenv("LANGFUSE_ENVIRONMENT", "")).strip()
    timeout_sec = float(_env_int("AGENT_LANGFUSE_HTTP_TIMEOUT_SEC", 30, minimum=3, maximum=120))

    return {
        "host": host,
        "public_key": public_key,
        "secret_key": secret_key,
        "environment": environment,
        "timeout_sec": timeout_sec,
    }


class LangfuseControlService:
    def __init__(self, settings: dict[str, Any] | None = None):
        self._settings = settings or resolve_langfuse_settings()

    def _ensure_credentials(self) -> None:
        missing: list[str] = []
        for key in ("host", "public_key", "secret_key"):
            if not str(self._settings.get(key, "")).strip():
                missing.append(key)
        if missing:
            raise LangfuseControlError(f"Langfuse credentials missing: {', '.join(missing)}")

    def _build_client(self):
        self._ensure_credentials()
        client, backend, error = build_langfuse_client(
            public_key=self._settings["public_key"],
            secret_key=self._settings["secret_key"],
            host=self._settings["host"],
            environment=self._settings.get("environment", ""),
            timeout_sec=float(self._settings.get("timeout_sec", 30.0) or 30.0),
        )
        if client is None:
            raise LangfuseControlError(error or "failed to build langfuse client")
        return client, backend

    def _build_http_client(self) -> LangfuseHTTPClient:
        self._ensure_credentials()
        return LangfuseHTTPClient(
            public_key=self._settings["public_key"],
            secret_key=self._settings["secret_key"],
            host=self._settings["host"],
            environment=self._settings.get("environment", ""),
            timeout_sec=float(self._settings.get("timeout_sec", 30.0) or 30.0),
        )

    @staticmethod
    def _mutation_allowed() -> bool:
        return str(os.getenv("AGENT_LANGFUSE_CONTROL_ALLOW_MUTATION", "")).strip().lower() in {
            "1",
            "true",
            "yes",
            "on",
        }

    def _ensure_mutation_allowed(self) -> None:
        if not self._mutation_allowed():
            raise LangfuseControlError(
                "Langfuse mutation is disabled. Set AGENT_LANGFUSE_CONTROL_ALLOW_MUTATION=true to enable."
            )

    @staticmethod
    def _openapi_url() -> str:
        return str(os.getenv("AGENT_LANGFUSE_OPENAPI_URL", "")).strip() or "https://cloud.langfuse.com/generated/api/openapi.yml"

    @staticmethod
    def _openapi_cache_ttl_sec() -> int:
        return _env_int("AGENT_LANGFUSE_OPENAPI_CACHE_TTL_SEC", 300, minimum=0, maximum=86400)

    @staticmethod
    def _openapi_policy_patterns(env_name: str) -> list[str]:
        raw = str(os.getenv(env_name, "")).strip()
        if not raw:
            return []
        tokens: list[str] = []
        for chunk in raw.replace("\n", ",").split(","):
            item = chunk.strip()
            if item:
                tokens.append(item)
        return tokens

    @staticmethod
    def _openapi_policy_matches(
        pattern: str,
        *,
        operation_id: str,
        method: str,
        path: str,
    ) -> bool:
        normalized_pattern = str(pattern or "").strip().lower()
        if not normalized_pattern:
            return False
        candidates = [
            str(operation_id or "").strip().lower(),
            f"{str(method or '').strip().upper()} {str(path or '').strip()}".lower(),
            f"{str(method or '').strip().upper()}:{str(path or '').strip()}".lower(),
            str(path or "").strip().lower(),
        ]
        for candidate in candidates:
            if not candidate:
                continue
            if fnmatchcase(candidate, normalized_pattern):
                return True
        return False

    def _is_openapi_operation_allowed(
        self,
        *,
        operation_id: str,
        method: str,
        path: str,
    ) -> bool:
        allowlist = self._openapi_policy_patterns("AGENT_LANGFUSE_OPENAPI_ALLOWLIST")
        denylist = self._openapi_policy_patterns("AGENT_LANGFUSE_OPENAPI_DENYLIST")

        if allowlist:
            if not any(
                self._openapi_policy_matches(pattern, operation_id=operation_id, method=method, path=path)
                for pattern in allowlist
            ):
                return False
        if denylist:
            if any(
                self._openapi_policy_matches(pattern, operation_id=operation_id, method=method, path=path)
                for pattern in denylist
            ):
                return False
        return True

    def _fetch_openapi_spec(self) -> dict[str, Any]:
        url = self._openapi_url()
        try:
            response = httpx.get(url, timeout=30.0)
        except Exception as exc:
            raise LangfuseControlError(f"failed to fetch OpenAPI spec: {exc}") from exc
        if response.status_code >= 400:
            raise LangfuseControlError(f"failed to fetch OpenAPI spec: HTTP {response.status_code}")
        text = response.text or ""
        try:
            return json.loads(text)
        except Exception:
            try:
                import yaml  # type: ignore
            except Exception as exc:
                raise LangfuseControlError(
                    "OpenAPI spec is YAML and PyYAML is unavailable. Install pyyaml or provide JSON spec URL."
                ) from exc
            try:
                payload = yaml.safe_load(text)
                if not isinstance(payload, dict):
                    raise LangfuseControlError("invalid OpenAPI spec format")
                return payload
            except Exception as exc:
                raise LangfuseControlError(f"failed to parse OpenAPI spec: {exc}") from exc

    def _load_openapi_spec(self, *, refresh: bool = False) -> dict[str, Any]:
        cache_key = self._openapi_url()
        ttl = self._openapi_cache_ttl_sec()
        now = time.time()
        with _OPENAPI_CACHE_LOCK:
            cached = _OPENAPI_CACHE.get(cache_key)
            if (
                not refresh
                and isinstance(cached, dict)
                and isinstance(cached.get("fetched_at"), (int, float))
                and isinstance(cached.get("spec"), dict)
                and (ttl <= 0 or (now - float(cached["fetched_at"])) < ttl)
            ):
                return dict(cached["spec"])

        spec = self._fetch_openapi_spec()
        with _OPENAPI_CACHE_LOCK:
            _OPENAPI_CACHE[cache_key] = {"fetched_at": now, "spec": spec}
        return dict(spec)

    @staticmethod
    def _openapi_operations(spec: dict[str, Any]) -> list[dict[str, Any]]:
        paths = spec.get("paths")
        if not isinstance(paths, dict):
            return []
        operations: list[dict[str, Any]] = []
        for path, methods in paths.items():
            if not isinstance(path, str) or not isinstance(methods, dict):
                continue
            for method, operation in methods.items():
                normalized_method = str(method or "").strip().lower()
                if normalized_method not in {"get", "post", "put", "patch", "delete"}:
                    continue
                if not isinstance(operation, dict):
                    continue
                operation_id = str(operation.get("operationId") or f"{normalized_method}_{path}").strip()
                summary = str(operation.get("summary") or operation.get("description") or "").strip()
                operations.append(
                    {
                        "operation_id": operation_id,
                        "method": normalized_method.upper(),
                        "path": path,
                        "mutating": normalized_method in {"post", "put", "patch", "delete"},
                        "summary": summary,
                        "tags": operation.get("tags") if isinstance(operation.get("tags"), list) else [],
                    }
                )
        operations.sort(key=lambda item: (item["path"], item["method"], item["operation_id"]))
        return operations

    @staticmethod
    def _resolve_openapi_operation(
        spec: dict[str, Any],
        *,
        operation_id: str | None = None,
        method: str | None = None,
        path: str | None = None,
    ) -> tuple[str, str, dict[str, Any]]:
        paths = spec.get("paths")
        if not isinstance(paths, dict):
            raise LangfuseControlError("OpenAPI spec has no paths")

        normalized_method = str(method or "").strip().lower()
        normalized_path = str(path or "").strip()
        normalized_operation_id = str(operation_id or "").strip()

        if normalized_operation_id:
            for candidate_path, methods in paths.items():
                if not isinstance(methods, dict):
                    continue
                for candidate_method, operation in methods.items():
                    if not isinstance(operation, dict):
                        continue
                    candidate_operation_id = str(operation.get("operationId") or "").strip()
                    if candidate_operation_id == normalized_operation_id:
                        method_upper = str(candidate_method).upper()
                        return method_upper, str(candidate_path), dict(operation)
            raise LangfuseControlError(f"operation_id not found in OpenAPI spec: {normalized_operation_id}")

        if not normalized_method or not normalized_path:
            raise LangfuseControlError("operation_id or method+path is required")

        path_item = paths.get(normalized_path)
        if not isinstance(path_item, dict):
            raise LangfuseControlError(f"path not found in OpenAPI spec: {normalized_path}")
        operation = path_item.get(normalized_method)
        if not isinstance(operation, dict):
            raise LangfuseControlError(f"method not found for path in OpenAPI spec: {normalized_method.upper()} {normalized_path}")
        return normalized_method.upper(), normalized_path, dict(operation)

    @staticmethod
    def _render_openapi_path(path_template: str, path_params: dict[str, Any]) -> str:
        final_path = str(path_template or "")
        for key, value in path_params.items():
            token = "{" + str(key) + "}"
            final_path = final_path.replace(token, quote(str(value), safe=""))
        if "{" in final_path or "}" in final_path:
            raise LangfuseControlError(f"missing required path params for path: {path_template}")
        return final_path

    @staticmethod
    def _is_mutating_method(method: str) -> bool:
        return str(method or "").strip().upper() in {"POST", "PUT", "PATCH", "DELETE"}

    def openapi_spec(self, *, full: bool = False, refresh: bool = False) -> dict[str, Any]:
        spec = self._load_openapi_spec(refresh=refresh)
        operations = self._openapi_operations(spec)
        allowed_operations = [
            item
            for item in operations
            if self._is_openapi_operation_allowed(
                operation_id=str(item.get("operation_id") or ""),
                method=str(item.get("method") or ""),
                path=str(item.get("path") or ""),
            )
        ]
        result: dict[str, Any] = {
            "url": self._openapi_url(),
            "fetched_at": _now_iso(),
            "openapi": spec.get("openapi"),
            "info": spec.get("info") if isinstance(spec.get("info"), dict) else {},
            "operation_count": len(allowed_operations),
            "operation_total_count": len(operations),
            "policy": {
                "allowlist": self._openapi_policy_patterns("AGENT_LANGFUSE_OPENAPI_ALLOWLIST"),
                "denylist": self._openapi_policy_patterns("AGENT_LANGFUSE_OPENAPI_DENYLIST"),
            },
        }
        if full:
            result["spec"] = spec
        return result

    def openapi_list_operations(self, *, refresh: bool = False) -> dict[str, Any]:
        spec = self._load_openapi_spec(refresh=refresh)
        operations = self._openapi_operations(spec)
        filtered = [
            item
            for item in operations
            if self._is_openapi_operation_allowed(
                operation_id=str(item.get("operation_id") or ""),
                method=str(item.get("method") or ""),
                path=str(item.get("path") or ""),
            )
        ]
        return {
            "url": self._openapi_url(),
            "count": len(filtered),
            "total_count": len(operations),
            "operations": filtered,
            "policy": {
                "allowlist": self._openapi_policy_patterns("AGENT_LANGFUSE_OPENAPI_ALLOWLIST"),
                "denylist": self._openapi_policy_patterns("AGENT_LANGFUSE_OPENAPI_DENYLIST"),
            },
        }

    def openapi_is_mutating(
        self,
        *,
        operation_id: str | None = None,
        method: str | None = None,
        path: str | None = None,
    ) -> bool:
        spec = self._load_openapi_spec(refresh=False)
        resolved_method, _resolved_path, _operation = self._resolve_openapi_operation(
            spec,
            operation_id=operation_id,
            method=method,
            path=path,
        )
        return self._is_mutating_method(resolved_method)

    def openapi_execute(self, params: dict[str, Any]) -> dict[str, Any]:
        refresh = bool(params.get("refresh_spec", False))
        spec = self._load_openapi_spec(refresh=refresh)
        operation_id = str(params.get("operation_id") or "").strip() or None
        method = str(params.get("method") or "").strip() or None
        path = str(params.get("path") or "").strip() or None
        resolved_method, path_template, operation = self._resolve_openapi_operation(
            spec,
            operation_id=operation_id,
            method=method,
            path=path,
        )
        resolved_operation_id = str(operation.get("operationId") or operation_id or f"{resolved_method}_{path_template}")

        if not str(path_template).startswith("/api/public/"):
            raise LangfuseControlError("only /api/public/* OpenAPI paths are allowed")
        if not self._is_openapi_operation_allowed(
            operation_id=resolved_operation_id,
            method=resolved_method,
            path=path_template,
        ):
            raise LangfuseControlError(
                "OpenAPI operation blocked by policy (AGENT_LANGFUSE_OPENAPI_ALLOWLIST / AGENT_LANGFUSE_OPENAPI_DENYLIST)"
            )

        path_params = params.get("path_params")
        query = params.get("query")
        body = params.get("body")
        if not isinstance(path_params, dict):
            path_params = {}
        if not isinstance(query, dict):
            query = {}
        if not isinstance(body, dict):
            body = None

        operation_parameters = operation.get("parameters")
        if isinstance(operation_parameters, list):
            for item in operation_parameters:
                if not isinstance(item, dict):
                    continue
                name = str(item.get("name") or "").strip()
                location = str(item.get("in") or "").strip()
                if not name:
                    continue
                if location == "path" and name not in path_params and name in params:
                    path_params[name] = params.get(name)
                if location == "query" and name not in query and name in params:
                    query[name] = params.get(name)

        if body is None and isinstance(params.get("request_body"), dict):
            body = params.get("request_body")

        final_path = self._render_openapi_path(path_template, path_params)
        if self._is_mutating_method(resolved_method):
            self._ensure_mutation_allowed()

        client = self._build_http_client()
        payload = client._transport.request_json(
            method=resolved_method,
            path=final_path.lstrip("/"),
            params=query if query else None,
            body=body,
        )
        return {
            "backend": "http-fallback",
            "meta": {
                "operation_id": resolved_operation_id,
                "method": resolved_method,
                "path": final_path,
                "mutating": self._is_mutating_method(resolved_method),
            },
            "data": _as_plain(payload),
        }

    def status(self) -> dict[str, Any]:
        self._ensure_credentials()
        _client, backend = self._build_client()
        return {
            "ok": True,
            "backend": backend,
            "environment": self._settings.get("environment", ""),
            "host": self._settings.get("host", ""),
            "checked_at": _now_iso(),
        }

    def traces_list(self, params: dict[str, Any]) -> dict[str, Any]:
        client, backend = self._build_client()
        payload = client.api.trace.list(**params)
        return {
            "backend": backend,
            "data": _as_plain(payload),
        }

    def trace_get(self, trace_id: str) -> dict[str, Any]:
        client, backend = self._build_client()
        payload = client.api.trace.get(trace_id)
        return {
            "backend": backend,
            "data": _as_plain(payload),
        }

    def observations_list(self, params: dict[str, Any]) -> dict[str, Any]:
        client, backend = self._build_client()
        payload = client.api.observations.get_many(**params)
        return {
            "backend": backend,
            "data": _as_plain(payload),
        }

    def prompt_get(self, *, name: str, label: str | None = None, version: int | None = None) -> dict[str, Any]:
        client, backend = self._build_client()
        payload = client.get_prompt(name, label=label, version=version, type="text")
        return {
            "backend": backend,
            "data": _as_plain(payload),
        }

    def prompt_upsert(
        self,
        *,
        name: str,
        prompt: Any,
        prompt_type: str = "text",
        labels: list[str] | None = None,
        tags: list[str] | None = None,
        commit_message: str | None = None,
        config: dict[str, Any] | None = None,
    ) -> dict[str, Any]:
        client, backend = self._build_client()
        payload = client.create_prompt(
            name=name,
            prompt=prompt,
            type=prompt_type,
            labels=labels,
            tags=tags,
            commit_message=commit_message,
            config=config,
        )
        return {
            "backend": backend,
            "data": _as_plain(payload),
        }

    def prompt_list(self, params: dict[str, Any]) -> dict[str, Any]:
        client = self._build_http_client()
        payload = client._transport.request_json(method="GET", path="api/public/v2/prompts", params=params)
        return {
            "backend": "http-fallback",
            "data": _as_plain(payload),
        }

    def prompt_delete(self, *, name: str, version: int | None = None, label: str | None = None) -> dict[str, Any]:
        self._ensure_mutation_allowed()
        client = self._build_http_client()
        payload = client._transport.request_json(
            method="DELETE",
            path=f"api/public/v2/prompts/{quote(name, safe='')}",
            params={"version": version, "label": label},
        )
        return {
            "backend": "http-fallback",
            "data": _as_plain(payload),
        }

    def prompt_promote_label(self, *, name: str, label: str, version: int | None = None) -> dict[str, Any]:
        self._ensure_mutation_allowed()
        client = self._build_http_client()
        body: dict[str, Any] = {"label": label}
        if version is not None:
            body["version"] = version
        payload = client._transport.request_json(
            method="POST",
            path=f"api/public/v2/prompts/{quote(name, safe='')}/labels",
            body=body,
        )
        return {
            "backend": "http-fallback",
            "data": _as_plain(payload),
        }

    def datasets_list(self, params: dict[str, Any]) -> dict[str, Any]:
        client = self._build_http_client()
        payload = client._transport.request_json(method="GET", path="api/public/v2/datasets", params=params)
        return {
            "backend": "http-fallback",
            "data": _as_plain(payload),
        }

    def datasets_create(self, params: dict[str, Any]) -> dict[str, Any]:
        self._ensure_mutation_allowed()
        name = str(params.get("name") or "").strip()
        if not name:
            raise LangfuseControlError("dataset name is required")
        body = {
            "name": name,
            "description": params.get("description"),
            "metadata": params.get("metadata") if isinstance(params.get("metadata"), dict) else None,
        }
        client = self._build_http_client()
        payload = client._transport.request_json(method="POST", path="api/public/v2/datasets", body=body)
        return {
            "backend": "http-fallback",
            "data": _as_plain(payload),
        }

    def dataset_items_upsert(self, *, dataset_id: str, items: list[dict[str, Any]]) -> dict[str, Any]:
        self._ensure_mutation_allowed()
        if not dataset_id:
            raise LangfuseControlError("dataset_id is required")
        if not items:
            raise LangfuseControlError("items are required")
        client = self._build_http_client()
        payload = client._transport.request_json(
            method="POST",
            path=f"api/public/v2/datasets/{quote(dataset_id, safe='')}/items",
            body={"items": items},
        )
        return {
            "backend": "http-fallback",
            "data": _as_plain(payload),
        }

    def dataset_import_from_traces(
        self,
        *,
        dataset_id: str,
        trace_ids: list[str],
        item_template: dict[str, Any] | None = None,
    ) -> dict[str, Any]:
        self._ensure_mutation_allowed()
        if not dataset_id:
            raise LangfuseControlError("dataset_id is required")
        if not trace_ids:
            raise LangfuseControlError("trace_ids are required")
        items: list[dict[str, Any]] = []
        for trace_id in trace_ids:
            item: dict[str, Any] = {
                "externalId": f"trace:{trace_id}",
                "input": {"trace_id": trace_id},
                "metadata": {"source": "trace-import", "trace_id": trace_id},
            }
            if isinstance(item_template, dict):
                for key, value in item_template.items():
                    if key not in item:
                        item[key] = value
            items.append(item)
        return self.dataset_items_upsert(dataset_id=dataset_id, items=items)

    def score_create(self, params: dict[str, Any]) -> dict[str, Any]:
        self._ensure_mutation_allowed()
        client = self._build_http_client()
        payload = client._transport.request_json(
            method="POST",
            path="api/public/scores",
            body={
                "name": params.get("name"),
                "traceId": params.get("trace_id"),
                "observationId": params.get("observation_id"),
                "value": params.get("value"),
                "comment": params.get("comment"),
                "metadata": params.get("metadata") if isinstance(params.get("metadata"), dict) else None,
            },
        )
        return {
            "backend": "http-fallback",
            "data": _as_plain(payload),
        }

    def annotation_create(self, params: dict[str, Any]) -> dict[str, Any]:
        self._ensure_mutation_allowed()
        client = self._build_http_client()
        payload = client._transport.request_json(
            method="POST",
            path="api/public/annotations",
            body={
                "traceId": params.get("trace_id"),
                "observationId": params.get("observation_id"),
                "label": params.get("label"),
                "comment": params.get("comment"),
                "metadata": params.get("metadata") if isinstance(params.get("metadata"), dict) else None,
            },
        )
        return {
            "backend": "http-fallback",
            "data": _as_plain(payload),
        }

    def raw_http(
        self,
        *,
        method: str,
        path: str,
        params: dict[str, Any] | None = None,
        body: dict[str, Any] | None = None,
    ) -> dict[str, Any]:
        safe_method = str(method or "GET").upper()
        safe_path = str(path or "").strip().lstrip("/")
        if safe_method not in {"GET", "POST", "PUT", "PATCH", "DELETE"}:
            raise LangfuseControlError("unsupported method")
        if not safe_path.startswith("api/public/"):
            raise LangfuseControlError("only api/public/* paths are allowed")

        if safe_method in {"POST", "PUT", "PATCH", "DELETE"} and not self._mutation_allowed():
            raise LangfuseControlError(
                "mutation via raw_http is disabled; set AGENT_LANGFUSE_CONTROL_ALLOW_MUTATION=true to enable"
            )

        client = self._build_http_client()
        payload = client._transport.request_json(
            method=safe_method,
            path=safe_path,
            params=params,
            body=body,
        )
        return {
            "backend": "http-fallback",
            "data": _as_plain(payload),
        }

    def execute(self, command: dict[str, Any]) -> dict[str, Any]:
        operation = str(command.get("operation") or "status").strip().lower()
        params = command.get("params")
        if not isinstance(params, dict):
            params = {}

        if operation == "status":
            result = self.status()
        elif operation == "traces.list":
            result = self.traces_list(params)
        elif operation == "trace.get":
            trace_id = str(params.get("trace_id") or params.get("id") or "").strip()
            if not trace_id:
                raise LangfuseControlError("trace_id is required")
            result = self.trace_get(trace_id)
        elif operation == "observations.list":
            result = self.observations_list(params)
        elif operation == "prompt.get":
            name = str(params.get("name") or "").strip()
            if not name:
                raise LangfuseControlError("name is required")
            version = params.get("version")
            try:
                version_int = int(version) if version is not None else None
            except Exception:
                version_int = None
            result = self.prompt_get(name=name, label=params.get("label"), version=version_int)
        elif operation == "prompt.list":
            result = self.prompt_list(params)
        elif operation == "prompt.upsert":
            name = str(params.get("name") or "").strip()
            if not name:
                raise LangfuseControlError("name is required")
            if "prompt" not in params:
                raise LangfuseControlError("prompt is required")
            labels = params.get("labels")
            tags = params.get("tags")
            if isinstance(labels, str):
                labels = [item.strip() for item in labels.split(",") if item.strip()]
            if isinstance(tags, str):
                tags = [item.strip() for item in tags.split(",") if item.strip()]
            result = self.prompt_upsert(
                name=name,
                prompt=params.get("prompt"),
                prompt_type=str(params.get("type") or "text"),
                labels=labels if isinstance(labels, list) else None,
                tags=tags if isinstance(tags, list) else None,
                commit_message=params.get("commit_message"),
                config=params.get("config") if isinstance(params.get("config"), dict) else None,
            )
        elif operation == "prompt.delete":
            name = str(params.get("name") or "").strip()
            if not name:
                raise LangfuseControlError("name is required")
            version = params.get("version")
            try:
                version_int = int(version) if version is not None else None
            except Exception:
                version_int = None
            result = self.prompt_delete(name=name, version=version_int, label=params.get("label"))
        elif operation == "prompt.promote_label":
            name = str(params.get("name") or "").strip()
            label = str(params.get("label") or "").strip()
            if not name:
                raise LangfuseControlError("name is required")
            if not label:
                raise LangfuseControlError("label is required")
            version = params.get("version")
            try:
                version_int = int(version) if version is not None else None
            except Exception:
                version_int = None
            result = self.prompt_promote_label(name=name, label=label, version=version_int)
        elif operation == "datasets.list":
            result = self.datasets_list(params)
        elif operation == "datasets.create":
            result = self.datasets_create(params)
        elif operation == "dataset.items.upsert":
            dataset_id = str(params.get("dataset_id") or "").strip()
            items = params.get("items")
            if not isinstance(items, list):
                raise LangfuseControlError("items must be a list")
            cast_items = [item for item in items if isinstance(item, dict)]
            result = self.dataset_items_upsert(dataset_id=dataset_id, items=cast_items)
        elif operation == "datasets.import_from_traces":
            dataset_id = str(params.get("dataset_id") or "").strip()
            trace_ids = params.get("trace_ids")
            if isinstance(trace_ids, str):
                trace_ids = [item.strip() for item in trace_ids.split(",") if item.strip()]
            if not isinstance(trace_ids, list):
                raise LangfuseControlError("trace_ids must be a list")
            cast_trace_ids = [str(item).strip() for item in trace_ids if str(item).strip()]
            template = params.get("item_template") if isinstance(params.get("item_template"), dict) else None
            result = self.dataset_import_from_traces(
                dataset_id=dataset_id,
                trace_ids=cast_trace_ids,
                item_template=template,
            )
        elif operation == "score.create":
            result = self.score_create(params)
        elif operation == "annotation.create":
            result = self.annotation_create(params)
        elif operation == "openapi.spec":
            result = self.openapi_spec(full=bool(params.get("full", False)), refresh=bool(params.get("refresh", False)))
        elif operation == "openapi.list_operations":
            result = self.openapi_list_operations(refresh=bool(params.get("refresh", False)))
        elif operation == "openapi.execute":
            result = self.openapi_execute(params)
        elif operation == "http.request":
            method = str(params.get("method") or "GET")
            path = str(params.get("path") or "")
            req_params = params.get("query")
            if not isinstance(req_params, dict):
                req_params = None
            body = params.get("body") if isinstance(params.get("body"), dict) else None
            result = self.raw_http(method=method, path=path, params=req_params, body=body)
        else:
            raise LangfuseControlError(f"unsupported operation: {operation}")

        return {
            "operation": operation,
            "executed_at": _now_iso(),
            "result": _redact(_as_plain(result)),
        }


def execute_control_message(message: str, *, settings: dict[str, Any] | None = None) -> dict[str, Any]:
    command = parse_control_message(message)
    service = LangfuseControlService(settings=settings)
    return service.execute(command)
