"""Agent configuration."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any


@dataclass
class RateLimitConfig:
    """Configuration for HTTP rate limiting."""

    enabled: bool = True
    backend: str = "memory"
    dsn: str | None = None
    namespace: str = "logos_adk_rate_limit"
    table_name: str = "rate_limit_events"
    limit_per_minute: int = 120
    burst: int = 30
    window_seconds: int = 60


@dataclass
class SecurityConfig:
    """Security policy configuration."""

    input_validation_enabled: bool = True
    prompt_shield_enabled: bool = True
    prompt_injection_threshold: float = 0.5
    prompt_injection_patterns: list[str] = field(default_factory=list)
    pii_detection_enabled: bool = True
    pii_blocked_types: list[str] = field(default_factory=lambda: ["ssn", "credit_card"])
    audit_logging_enabled: bool = True
    input_max_length: int = 20_000
    input_min_length: int = 1
    output_max_length: int = 20_000
    reject_null_bytes: bool = True
    input_pii_action: str = "selective"
    output_pii_action: str = "selective"
    audit_redact_pii: bool = True
    audit_retention_days: int = 30
    rate_limit: RateLimitConfig = field(default_factory=RateLimitConfig)


@dataclass
class ReliabilityConfig:
    """Reliability policy configuration."""

    timeout_seconds: float = 60.0
    retry_max_attempts: int = 3
    retry_base_delay: float = 0.25
    retry_backoff: str = "exponential"
    circuit_breaker_failure_threshold: int = 5
    circuit_breaker_recovery_timeout: float = 30.0
    fallback_models: list[str] = field(default_factory=list)


@dataclass
class RoutingConfig:
    """Configuration for autonomous model routing."""

    enabled: bool = False
    budget_preference: str = "balanced"
    task_budget_usd: float | None = None
    task_budget_tokens: int | None = None
    fail_on_budget_exhausted: bool = False
    ledger_backend: str = "sqlite"
    ledger_path: str = ".logos_adk/spend_ledger.db"
    ledger_dsn: str | None = None
    workspace_soft_limit_usd: float | None = None
    session_soft_limit_usd: float | None = None
    threshold_ratio: float = 0.8
    simple_task_types: list[str] = field(
        default_factory=lambda: [
            "support",
            "editing",
            "rewrite",
            "classification",
            "extraction",
            "summarization",
        ]
    )
    critical_task_types: list[str] = field(
        default_factory=lambda: [
            "analysis",
            "architecture",
            "planning",
            "code",
            "strategy",
            "security",
            "migration",
        ]
    )
    simple_prompt_markers: list[str] = field(
        default_factory=lambda: [
            "fix typo",
            "correct typo",
            "rewrite",
            "rephrase",
            "summarize",
            "short reply",
            "classify",
            "extract",
        ]
    )
    critical_prompt_markers: list[str] = field(
        default_factory=lambda: [
            "analyze",
            "architecture",
            "debug",
            "root cause",
            "security",
            "production",
            "critical",
            "migration",
            "design",
            "strategy",
        ]
    )
    medium_length_threshold: int = 180
    high_length_threshold: int = 600


@dataclass
class SelfQAConfig:
    """Configuration for autonomous self-verification before returning a result."""

    enabled: bool = False
    min_assertions: int = 2
    max_assertions: int = 3
    max_retries: int = 1
    fail_closed: bool = True


@dataclass
class ContextWindowConfig:
    """Configuration for context window management and token optimization."""

    max_context_tokens: int = 0  # 0 = disabled
    reserved_output_tokens: int = 4096
    strategy: str = "chunked_summary"  # "truncate" | "sliding_window" | "chunked_summary"
    chunk_size: int = 10
    summary_max_tokens: int = 300
    max_summary_chain: int = 5
    keep_recent_messages: int = 6
    summary_model: str | None = None
    summary_system_prompt: str | None = None
    memory_max_tokens: int = 0  # 0 = no limit
    smart_tool_selection: bool = False          # P2: enable task-hint-based tool filtering
    semantic_cache_max_entries: int = 0         # P2: 0 = disabled
    auto_detect_model_limit: bool = False       # P2: auto-set max_context_tokens from model


@dataclass
class StateConfig:
    """Configuration for persistent agent state."""

    backend: str | None = None
    dsn: str | None = None
    path: str = ".logos_adk/state.db"
    table_name: str = "agent_state_versions"
    shards: list["StateConfig"] = field(default_factory=list)


@dataclass
class TaskQueueConfig:
    """Configuration for background task execution."""

    backend: str = "postgresql"
    dsn: str | None = None
    path: str = ".logos_adk/tasks.db"
    concurrency: int = 4
    max_retries: int = 2
    idempotency_ttl_seconds: int = 86_400


@dataclass
class RetrievalOpsConfig:
    """Configuration for retrieval-learning operator policies."""

    dsn: str | None = None
    path: str = ".logos_adk/retrieval_learning.db"
    table_prefix: str = "retrieval_learning"
    source_document_ttl_days: int = 30
    max_source_documents_per_source: int = 20
    dedupe_window_seconds: int = 600


@dataclass
class LearningConfig:
    """Configuration for learning-loop persistence and policies."""

    retrieval: RetrievalOpsConfig = field(default_factory=RetrievalOpsConfig)


@dataclass
class ScalingConfig:
    """Configuration for horizontal scaling and request distribution."""

    distributed: bool = False
    replicas: int = 1
    load_balancer: str = "round_robin"
    session_affinity: bool = False
    task_queue: TaskQueueConfig = field(default_factory=TaskQueueConfig)


@dataclass
class ProviderConfig:
    """Configuration for a provider."""

    type: str
    model: str | None = None
    base_url: str | None = None
    proxy: str | None = None
    api_key: str | None = None
    api_key_env: str | None = None
    extra: dict[str, Any] = field(default_factory=dict)


@dataclass
class AgentConfig:
    """Configuration for an Agent (config phase)."""

    name: str
    agent_class: str | None = None
    agent_module: str | None = None
    agent_factory: str | None = None
    model: Any | None = None
    provider: ProviderConfig | None = None
    system_prompt: str | None = None
    role: str | None = None
    goal: str | None = None
    backstory: str | None = None
    tools: list[Any] = field(default_factory=list)
    memories: list[Any] = field(default_factory=list)
    mcp_servers: list[Any] = field(default_factory=list)
    observers: list[Any] = field(default_factory=list)
    output_schema: Any | None = None
    input_guardrails: list[Any] = field(default_factory=list)
    output_guardrails: list[Any] = field(default_factory=list)
    event_handlers: dict[str, list[Any]] = field(default_factory=dict)
    cache_backend: Any | None = None
    cache_config: Any | None = None
    knowledge_base: Any | None = None
    learning: LearningConfig = field(default_factory=LearningConfig)
    scaling: ScalingConfig = field(default_factory=ScalingConfig)
    state: StateConfig = field(default_factory=StateConfig)
    security: SecurityConfig = field(default_factory=SecurityConfig)
    reliability: ReliabilityConfig = field(default_factory=ReliabilityConfig)
    routing: RoutingConfig = field(default_factory=RoutingConfig)
    self_qa: SelfQAConfig = field(default_factory=SelfQAConfig)
    context_window: ContextWindowConfig = field(default_factory=ContextWindowConfig)
    metadata: dict[str, Any] = field(default_factory=dict)
    disabled_tools: list[str] = field(default_factory=list)
