package config

import (
	"testing"

	"gopkg.in/yaml.v3"
)

// TestAgentConfigParseMinimal verifies that a minimal config YAML (with only
// required fields) parses into AgentConfig without error.
func TestAgentConfigParseMinimal(t *testing.T) {
	const minimalYAML = `
agent:
  id: test-bot
  name: Test Bot
  enabled: true
bus:
  nats_url: "nats://127.0.0.1:4250"
  ctrl_url: "http://127.0.0.1:8470"
llm:
  primary:
    provider: openai
    model: gpt-4o
`
	var cfg AgentConfig
	if err := yaml.Unmarshal([]byte(minimalYAML), &cfg); err != nil {
		t.Fatalf("failed to parse minimal config: %v", err)
	}
	if cfg.Agent.ID != "test-bot" {
		t.Errorf("expected agent.id=test-bot, got %q", cfg.Agent.ID)
	}
	if cfg.Bus.NatsURL != "nats://127.0.0.1:4250" {
		t.Errorf("expected bus.nats_url, got %q", cfg.Bus.NatsURL)
	}
	if cfg.LLM.Primary.Provider != "openai" {
		t.Errorf("expected provider=openai, got %q", cfg.LLM.Primary.Provider)
	}
}

// TestAgentConfigIgnoresRemovedSections verifies that YAML containing the
// removed sections (agents, observability, resilience) still parses without
// error. yaml.v3 silently ignores unknown keys.
func TestAgentConfigIgnoresRemovedSections(t *testing.T) {
	const yamlWithRemoved = `
agent:
  id: legacy-bot
  name: Legacy Bot
  enabled: true
bus:
  nats_url: "nats://127.0.0.1:4250"
  ctrl_url: "http://127.0.0.1:8470"
llm:
  primary:
    provider: openai
    model: gpt-4o

# These sections were removed from the schema but may still exist in old YAMLs.
agents:
  peers:
    - id: other-bot
      capabilities: [general]
      room: "!abc:server.com"
  delegation:
    enabled: false
  protocol:
    format: json
    channel: matrix

observability:
  logging:
    level: info
    format: json
  metrics:
    enabled: false
  health:
    enabled: true
    port: 8080
  tracing:
    enabled: false

resilience:
  circuit_breaker:
    failure_threshold: 5
    timeout: 30s
  retry:
    max_attempts: 2
    backoff: exponential
  shutdown:
    timeout: 10s
  queue:
    enabled: true
    max_size: 100
`
	var cfg AgentConfig
	if err := yaml.Unmarshal([]byte(yamlWithRemoved), &cfg); err != nil {
		t.Fatalf("parsing config with removed sections should succeed, got: %v", err)
	}
	if cfg.Agent.ID != "legacy-bot" {
		t.Errorf("expected agent.id=legacy-bot, got %q", cfg.Agent.ID)
	}
}

// TestAgentConfigParseFull verifies that a config YAML with all active sections
// parses correctly, including personality with communication.
func TestAgentConfigParseFull(t *testing.T) {
	const fullYAML = `
agent:
  id: full-bot
  name: Full Bot
  version: "1.0.0"
  enabled: true
  description: "A fully configured bot"
  tags: [test, full]

personality:
  tone: friendly
  verbosity: concise
  language: es
  role: "asistente general"
  communication:
    formality: semiformal
    humor: subtle
    personality: pragmatic
    response_style: structured
    quirks: ["usa analogias"]
    avoid_topics: ["politica"]
    catchphrases: ["interesante"]

llm:
  primary:
    provider: openai
    model: gpt-4o
    api_key_env: OPENAI_API_KEY
    max_tokens: 4096
    temperature: 0.7
  tool_use:
    enabled: true
    max_iterations: 5

bus:
  nats_url: "nats://127.0.0.1:4250"
  ctrl_url: "http://127.0.0.1:8470"
  handle: full
  threads:
    enabled: true
    auto_thread: false

tools:
  ssh:
    enabled: false
  http:
    enabled: true
    allowed_domains: ["api.example.com"]
    timeout: 10s

security:
  sanitize:
    enabled: true
    mode: warn
    min_severity: medium
  tool_rate_limit:
    enabled: true
    max_calls_per_min: 10

storage:
  base_path: "/data/full-bot"

memory:
  enabled: true
  window_size: 30

skills:
  enabled: true
  path: "skills/"
  categories: ["devops"]
  timeout: 60s
`
	var cfg AgentConfig
	if err := yaml.Unmarshal([]byte(fullYAML), &cfg); err != nil {
		t.Fatalf("failed to parse full config: %v", err)
	}

	// Verify key fields
	if cfg.Agent.ID != "full-bot" {
		t.Errorf("agent.id: got %q", cfg.Agent.ID)
	}
	if cfg.Personality.Communication.Humor != "subtle" {
		t.Errorf("personality.communication.humor: got %q", cfg.Personality.Communication.Humor)
	}
	if len(cfg.Personality.Communication.Quirks) != 1 {
		t.Errorf("personality.communication.quirks: expected 1, got %d", len(cfg.Personality.Communication.Quirks))
	}
	if !cfg.LLM.ToolUse.Enabled {
		t.Error("llm.tool_use.enabled should be true")
	}
	if !cfg.Tools.HTTP.Enabled {
		t.Error("tools.http.enabled should be true")
	}
	if cfg.Storage.BasePath != "/data/full-bot" {
		t.Errorf("storage.base_path: got %q", cfg.Storage.BasePath)
	}
	if !cfg.Memory.Enabled {
		t.Error("memory.enabled should be true")
	}
	if !cfg.Skills.Enabled {
		t.Error("skills.enabled should be true")
	}
	if !cfg.Security.Sanitize.Enabled {
		t.Error("security.sanitize.enabled should be true")
	}
}
