# Copyright 2024 Klira AI
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Clinical logging functions — create child spans of the current span."""

from __future__ import annotations

from typing import Any

from opentelemetry import trace

_tracer = trace.get_tracer("klira")


def log_clinical_decision(
    decision: str,
    reasoning: str | None = None,
    confidence: float | None = None,
    **extra: Any,
) -> None:
    """Log a clinical decision as a child span."""
    attrs: dict[str, Any] = {
        "klira.entity_type": "clinical_decision",
        "klira.entity_name": "clinical_decision",
        "klira.clinical.decision": decision,
    }
    if reasoning is not None:
        attrs["klira.clinical.reasoning"] = reasoning
    if confidence is not None:
        attrs["klira.clinical.confidence"] = confidence
    attrs.update({f"klira.clinical.{k}": v for k, v in extra.items()})

    with _tracer.start_as_current_span("klira.clinical.decision", attributes=attrs):
        pass


def log_human_escalation(
    reason: str,
    urgency: str = "normal",
    **extra: Any,
) -> None:
    """Log a human escalation event as a child span."""
    attrs: dict[str, Any] = {
        "klira.entity_type": "human_escalation",
        "klira.entity_name": "human_escalation",
        "klira.clinical.escalation_reason": reason,
        "klira.clinical.urgency": urgency,
    }
    attrs.update({f"klira.clinical.{k}": v for k, v in extra.items()})

    with _tracer.start_as_current_span("klira.clinical.escalation", attributes=attrs):
        pass


def log_agent_handoff(
    from_agent: str,
    to_agent: str,
    reason: str | None = None,
    **extra: Any,
) -> None:
    """Log an agent handoff as a child span."""
    attrs: dict[str, Any] = {
        "klira.entity_type": "agent_handoff",
        "klira.entity_name": "agent_handoff",
        "klira.clinical.from_agent": from_agent,
        "klira.clinical.to_agent": to_agent,
    }
    if reason is not None:
        attrs["klira.clinical.handoff_reason"] = reason
    attrs.update({f"klira.clinical.{k}": v for k, v in extra.items()})

    with _tracer.start_as_current_span("klira.clinical.handoff", attributes=attrs):
        pass


def log_safety_check(
    check_type: str,
    passed: bool,
    details: str | None = None,
    **extra: Any,
) -> None:
    """Log a safety check as a child span."""
    attrs: dict[str, Any] = {
        "klira.entity_type": "safety_check",
        "klira.entity_name": check_type,
        "klira.clinical.check_type": check_type,
        "klira.clinical.check_passed": passed,
    }
    if details is not None:
        attrs["klira.clinical.check_details"] = details
    attrs.update({f"klira.clinical.{k}": v for k, v in extra.items()})

    with _tracer.start_as_current_span("klira.clinical.safety_check", attributes=attrs):
        pass


def log_rag_retrieval(
    source: str,
    query: str,
    result_count: int = 0,
    **extra: Any,
) -> None:
    """Log a RAG retrieval event as a child span."""
    attrs: dict[str, Any] = {
        "klira.entity_type": "rag_retrieval",
        "klira.entity_name": "rag_retrieval",
        "klira.clinical.rag_source": source,
        "klira.clinical.rag_query": query,
        "klira.clinical.rag_result_count": result_count,
    }
    attrs.update({f"klira.clinical.{k}": v for k, v in extra.items()})

    with _tracer.start_as_current_span(
        "klira.clinical.rag_retrieval", attributes=attrs
    ):
        pass
