"""Canonical attribute constants for OTEL span attributes.

Single source of truth for all attribute keys used across the SDK.
Prevents string drift between signals.py, client.py, bulk.py, and wrappers.py.

v8.0.0: Created as part of Signals Revamp Phase 1.
"""

# Core signal attributes
ATTR_EVENT_NAME = "agentbill.event_name"
ATTR_IS_BUSINESS_EVENT = "agentbill.is_business_event"
ATTR_IDEMPOTENCY_KEY = "agentbill.idempotency_key"
ATTR_DATA_SOURCE = "agentbill.data_source"

# Identity
ATTR_CUSTOMER_ID = "agentbill.customer_id"
ATTR_AGENT_ID = "agentbill.agent_id"

# Business data
ATTR_REVENUE = "agentbill.revenue"
ATTR_CURRENCY = "agentbill.currency"
ATTR_EVENT_TYPE = "agentbill.event_type"
ATTR_EVENT_VALUE = "agentbill.event_value"

# Linking
ATTR_SESSION_ID = "agentbill.session_id"
ATTR_ORDER_ID = "agentbill.order_id"
ATTR_ORDER_EXTERNAL_ID = "agentbill.order_external_id"
ATTR_PARENT_SPAN_ID = "agentbill.parent_span_id"
ATTR_METADATA = "agentbill.metadata"

# AI telemetry (OpenTelemetry Semantic Conventions)
ATTR_MODEL = "gen_ai.request.model"
ATTR_PROVIDER = "gen_ai.system"
ATTR_PROMPT_TOKENS = "gen_ai.usage.prompt_tokens"
ATTR_COMPLETION_TOKENS = "gen_ai.usage.completion_tokens"
ATTR_TOTAL_TOKENS = "gen_ai.usage.total_tokens"
ATTR_LATENCY_MS = "agentbill.latency_ms"
ATTR_PROMPT_HASH = "agentbill.prompt_hash"

# Modality / operation name (OTEL Semantic Convention: gen_ai.operation.name)
# Official values: chat, embeddings, text_completion, create_image, audio_speech, audio_transcription
ATTR_OPERATION_NAME = "gen_ai.operation.name"

# Image generation — request params (pricing tier) vs usage (quantity billed)
ATTR_IMAGE_SIZE = "gen_ai.request.image_size"          # e.g. "1024x1024" — determines price tier
ATTR_IMAGE_QUALITY = "gen_ai.request.image_quality"    # e.g. "hd", "standard" — determines price tier
ATTR_IMAGE_COUNT = "gen_ai.usage.image_count"          # actual images generated — quantity billed

# Audio — request params vs usage
ATTR_AUDIO_INPUT_FORMAT = "gen_ai.request.audio_input_format"   # e.g. "mp3", "wav" — input config
ATTR_AUDIO_OUTPUT_FORMAT = "gen_ai.request.audio_output_format" # e.g. "mp3", "opus" — input config
ATTR_AUDIO_DURATION_SECONDS = "gen_ai.usage.audio_duration_seconds"  # actual duration — quantity billed

# TTS — request params vs usage
ATTR_TTS_VOICE = "gen_ai.request.tts_voice"            # e.g. "alloy", "nova" — determines price tier
ATTR_TTS_CHARACTERS = "gen_ai.usage.characters"        # actual characters processed — quantity billed

# Embedding — request params vs usage
ATTR_EMBEDDING_DIMENSIONS = "gen_ai.request.embedding_dimensions"  # requested dims — determines price tier
ATTR_EMBEDDING_INPUT_COUNT = "gen_ai.usage.embedding_input_count"  # actual inputs — quantity billed

# Cache attributes
ATTR_CACHE_HIT = "agentbill.cache_hit"
ATTR_FROM_CACHE = "agentbill.from_cache"
ATTR_TOKENS_SAVED = "agentbill.tokens_saved"
ATTR_COST_SAVED = "agentbill.cost_saved"

# Cost tracing (Phase 1: enable_cost_tracing flag)
ATTR_COST_TRACING_ENABLED = "agentbill.cost_tracing.enabled"

# Manual cost (Phase 3 – two-variant model)
ATTR_COST_PROVIDED = "agentbill.cost.provided"  # bool: server skips model_pricing
ATTR_COST_PROVIDER = "agentbill.cost.provider"  # str: maps from CostData.vendor
ATTR_COST_AMOUNT = "agentbill.cost.amount"      # float: pre-calculated cost
ATTR_COST_CURRENCY = "agentbill.cost.currency"  # str: currency code

# Business grouping (whitelist)
GROUPING_KEYS = frozenset({"session_id", "workflow_id", "batch_id", "correlation_id"})

# Bulk
ATTR_BULK_INDEX = "agentbill.bulk_index"
ATTR_BULK_REQUEST = "agentbill.bulk_request"

# Resource / SDK constants
RESOURCE_SERVICE_NAME = "agentbill-python-sdk"
SDK_VERSION = "9.5.1"
SCOPE_NAME = "agentbill.signals"
SCOPE_NAME_BULK = "agentbill.signals.bulk"
SIGNAL_SPAN_NAME = "agentbill.trace.signal"
