from typing import List

import dataiku
from backend.config import get_config_v2
from backend.utils.api_clients import AH_GLOBAL_API_CLIENT
from backend.utils.general_utils import time_cached
from backend.utils.logging_utils import get_logger

logger = get_logger(__name__)

HTTP_HEADERS_CONTEXT_KEY = "dkuLLMMeshOriginalRequestHeaders"

FORBIDDEN_HTTP_HEADERS = {
    "authorization",
    "cookie",
    "set-cookie",
    "x-dku-apiticket",
    "x-dku-apikey",
    "x-dku-ipythonsharedsecret",
}


# user info properties:
# login(self)
# display_name(self):
# groups(self):
# email(self):
# enabled(self):
@time_cached(ttl_seconds=10)
def get_user_info(user: str):
    return AH_GLOBAL_API_CLIENT.get_user(user).get_info()


_DSS_VERSION_CACHE = None


def _as_bool(value, default: bool) -> bool:
    if value is None:
        return default
    if isinstance(value, str):
        return value.lower() == "true"
    return bool(value)


def get_agent_context(user: str, conv_id: str, *, client_ip: str = None, user_agent: str = None):
    from backend.utils.dss_utils import compare_versions
    from flask import request

    global _DSS_VERSION_CACHE

    user_info = get_user_info(user).get_raw()
    resolved_client_ip = client_ip or ""
    resolved_user_agent = user_agent or ""
    include_user_agent_in_context = _as_bool(get_config_v2().get("includeUserAgentInContext", False), False)
    include_client_ip_in_context = _as_bool(get_config_v2().get("includeClientIPInContext", False), False)
    cont = {
        "callerSecurityTokens": format_security_tokens(user_info),
        "dku_user_email": user_info.get("email", ""),
        "dku_user_login": user_info.get("login", ""),
        "dku_user_display_name": user_info.get("displayName", ""),
        "conversationId": conv_id,
        "dkuOnBehalfOf": user_info.get("login", ""),
        "dkuOnBehalfOfEmailAddress": user_info.get("email", ""),
        "dkuOnBehalfOfDisplayName": user_info.get("displayName", ""),
    }
    if include_client_ip_in_context:
        cont["dkuOnBehalfOfClientIP"] = resolved_client_ip
    if include_user_agent_in_context:
        cont["dkuOnBehalfOfUserAgent"] = resolved_user_agent
    # Only send callerTicket for dss >= 14.3.2 to make sure they are redacted properly
    if _DSS_VERSION_CACHE is None:
        _DSS_VERSION_CACHE = AH_GLOBAL_API_CLIENT.get_instance_info().raw.get("dssVersion", "0.0.0")
    dku_caller_ticket_setting = get_config_v2().get("dkuCallerTicket", True)
    if isinstance(dku_caller_ticket_setting, str):
        dku_caller_ticket_enabled = dku_caller_ticket_setting.lower() == "true"
    else:
        dku_caller_ticket_enabled = bool(dku_caller_ticket_setting)

    if compare_versions(_DSS_VERSION_CACHE, "14.3.2") >= 0 and dku_caller_ticket_enabled:
        cont["dkuCallerTicket"] = AH_GLOBAL_API_CLIENT.get_ticket_from_browser_headers(
            headers_dict=dict(request.headers)
        )
    return cont


def format_security_tokens(user_info) -> List[str]:
    user_data = []
    user_data.append(f"dss_user_login:{user_info.get('login', '')}")
    user_data.append(f"dss_user_emailaddress:{user_info.get('email', '')}")
    return user_info.get("groups", []) + [f"dss_group:{group}" for group in user_info.get("groups", [])] + user_data
