"""Canonical span attribute constants for standardized trace formats (PROD-382).

Single source of truth for all Klira span attribute names.
All adapters and guardrails MUST use these constants instead of inline strings.
"""

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# GenAI Semantic Convention Attributes (OpenTelemetry standard)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ATTR_GEN_AI_SYSTEM = "gen_ai.system"
ATTR_GEN_AI_REQUEST_MODEL = "gen_ai.request.model"
ATTR_GEN_AI_RESPONSE_MODEL = "gen_ai.response.model"
ATTR_GEN_AI_INPUT_TOKENS = "gen_ai.usage.input_tokens"
ATTR_GEN_AI_OUTPUT_TOKENS = "gen_ai.usage.output_tokens"
ATTR_GEN_AI_FINISH_REASONS = "gen_ai.response.finish_reasons"

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Klira Entity Attributes (on all Klira-owned spans)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ATTR_ENTITY_TYPE = "klira.entity_type"
ATTR_ENTITY_NAME = "klira.entity_name"
ATTR_USER_ID = "klira.user_id"

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Guardrails Attributes (canonical names — replaces all variants)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ATTR_GUARDRAILS_DIRECTION = "klira.guardrails.direction"
ATTR_GUARDRAILS_MATCHED_POLICIES = "klira.guardrails.matched_policies"
ATTR_GUARDRAILS_MATCHED_PATTERNS = "klira.guardrails.matched_patterns"
ATTR_GUARDRAILS_BLOCKING_POLICIES = "klira.guardrails.blocking_policies"
ATTR_GUARDRAILS_AUGMENTATION_APPLIED = "klira.guardrails.augmentation_applied"
ATTR_GUARDRAILS_AUGMENTATION_POLICIES = "klira.guardrails.augmentation_policies"
ATTR_GUARDRAILS_GUIDELINES_COUNT = "klira.guardrails.guidelines_count"
ATTR_GUARDRAILS_GUIDELINES = "klira.guardrails.guidelines"

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Compliance Decision Attributes
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ATTR_COMPLIANCE_DIRECTION = "klira.compliance.direction"
ATTR_COMPLIANCE_ALLOWED = "klira.compliance.decision.allowed"
ATTR_COMPLIANCE_ACTION = "klira.compliance.decision.action"
ATTR_COMPLIANCE_METHOD = "klira.compliance.evaluation.method"
ATTR_COMPLIANCE_LAYER = "klira.compliance.decision.layer"
ATTR_COMPLIANCE_POLICIES_MATCHED = "klira.compliance.policies.matched"
ATTR_COMPLIANCE_POLICIES_VIOLATED = "klira.compliance.policies.violated"
ATTR_COMPLIANCE_BLOCK_REASON = "klira.compliance.block.reason"

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# LLM Augmentation Attributes (on klira.llm.* spans)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ATTR_LLM_AUGMENTED = "klira.guardrails.augmentation_applied"
ATTR_LLM_POLICIES_INJECTED = "klira.guardrails.augmentation_policies_count"
ATTR_LLM_POLICY_LIST = "klira.guardrails.augmentation_policy_names"

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Standardized Guideline Injection Format
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
GUIDELINE_HEADER = "\n\nIMPORTANT POLICY DIRECTIVES:"
GUIDELINE_BULLET = "\u2022"  # bullet character

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Span Names (canonical)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SPAN_USER_MESSAGE = "klira.user.message"
SPAN_GUARDRAILS_INPUT = "klira.guardrails.input"
SPAN_GUARDRAILS_OUTPUT = "klira.guardrails.output"
SPAN_GUARDRAILS_EVALUATE = "klira.guardrails.evaluate"
SPAN_GUARDRAILS_ROUTE_DECISION = "klira.guardrails.route_decision"
SPAN_GUARDRAILS_FAST_RULES = "klira.guardrails.fast_rules"
SPAN_COMPLIANCE_ALLOWED = "klira.compliance.allowed"
SPAN_COMPLIANCE_AUGMENTED = "klira.compliance.augmented"
SPAN_COMPLIANCE_BLOCKED = "klira.compliance.blocked"


def llm_span_name(provider: str) -> str:
    """Generate the canonical LLM span name for a provider.

    Args:
        provider: Lowercase provider name (e.g., "anthropic", "openai", "gemini")

    Returns:
        Span name like "klira.llm.anthropic"
    """
    return f"klira.llm.{provider.lower()}"


def format_guidelines(guidelines: list[str]) -> str:
    """Format guidelines using the standardized injection format.

    Args:
        guidelines: List of guideline strings

    Returns:
        Formatted guidelines string ready for prompt injection
    """
    guideline_lines = "\n".join(
        [f"{GUIDELINE_BULLET} {g}" for g in guidelines]
    )
    return f"{GUIDELINE_HEADER}\n{guideline_lines}\n"
