package config_test

import (
	"os"
	"path/filepath"
	"strings"
	"testing"

	"iop/packages/go/config"
)

func TestLoadEdge_EdgeIdentity(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := "server:\n  listen: \"0.0.0.0:9090\"\nedge:\n  id: \"edge-dgx-group\"\n  name: \"DGX Group\"\n"
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.Edge.ID != "edge-dgx-group" {
		t.Fatalf("expected edge.id=%q, got %q", "edge-dgx-group", cfg.Edge.ID)
	}
	if cfg.Edge.Name != "DGX Group" {
		t.Fatalf("expected edge.name=%q, got %q", "DGX Group", cfg.Edge.Name)
	}
}

func TestLoadEdge_EdgeIdentityEmptyByDefault(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	if err := os.WriteFile(f, []byte("server:\n  listen: \"0.0.0.0:9090\"\n"), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.Edge.ID != "" || cfg.Edge.Name != "" {
		t.Fatalf("expected empty edge identity by default, got id=%q name=%q", cfg.Edge.ID, cfg.Edge.Name)
	}
}

func TestLoadEdge_ConsoleTimeoutDefault(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	if err := os.WriteFile(f, []byte("server:\n  listen: \"0.0.0.0:9090\"\n"), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.Console.TimeoutSec != 120 {
		t.Fatalf("expected default timeout_sec=120, got %d", cfg.Console.TimeoutSec)
	}
	if cfg.Console.Adapter != "cli" {
		t.Fatalf("expected default console.adapter=%q, got %q", "cli", cfg.Console.Adapter)
	}
	if cfg.Console.ResolveTarget() != "claude" {
		t.Fatalf("expected default console.target=%q, got %q", "claude", cfg.Console.ResolveTarget())
	}
}

func TestLoadEdge_OpenAIDefaults(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	if err := os.WriteFile(f, []byte("server:\n  listen: \"0.0.0.0:9090\"\n"), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.OpenAI.Enabled {
		t.Fatal("expected openai.enabled=false by default")
	}
	if cfg.OpenAI.Listen != "0.0.0.0:18081" {
		t.Fatalf("expected openai.listen default, got %q", cfg.OpenAI.Listen)
	}
	if cfg.OpenAI.Adapter != "ollama" {
		t.Fatalf("expected openai.adapter=%q, got %q", "ollama", cfg.OpenAI.Adapter)
	}
	if cfg.OpenAI.SessionID != "openai" {
		t.Fatalf("expected openai.session_id=%q, got %q", "openai", cfg.OpenAI.SessionID)
	}
	if cfg.OpenAI.TimeoutSec != 120 {
		t.Fatalf("expected openai.timeout_sec=120, got %d", cfg.OpenAI.TimeoutSec)
	}
	if !cfg.OpenAI.StrictOutput {
		t.Fatal("expected openai.strict_output=true")
	}
	if cfg.OpenAI.StrictStreamBuffer {
		t.Fatal("expected openai.strict_stream_buffer=false")
	}
	if cfg.Metrics.Port != 19092 {
		t.Fatalf("expected metrics.port=19092, got %d", cfg.Metrics.Port)
	}
}

func TestLoadEdge_OpenAIOverride(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
openai:
  enabled: true
  listen: "127.0.0.1:8088"
  node: "node0"
  adapter: "ollama"
  target: "llama-test"
  models:
    - "llama-test"
  session_id: "cline"
  timeout_sec: 45
  strict_output: false
  strict_stream_buffer: true
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if !cfg.OpenAI.Enabled {
		t.Fatal("expected openai.enabled=true")
	}
	if cfg.OpenAI.Listen != "127.0.0.1:8088" || cfg.OpenAI.NodeRef != "node0" {
		t.Fatalf("unexpected openai routing config: %+v", cfg.OpenAI)
	}
	if cfg.OpenAI.Target != "llama-test" || len(cfg.OpenAI.Models) != 1 || cfg.OpenAI.Models[0] != "llama-test" {
		t.Fatalf("unexpected openai model config: %+v", cfg.OpenAI)
	}
	if cfg.OpenAI.SessionID != "cline" || cfg.OpenAI.TimeoutSec != 45 {
		t.Fatalf("unexpected openai execution config: %+v", cfg.OpenAI)
	}
	if cfg.OpenAI.StrictOutput {
		t.Fatalf("unexpected openai strict output config: %+v", cfg.OpenAI)
	}
	if !cfg.OpenAI.StrictStreamBuffer {
		t.Fatalf("unexpected openai strict stream buffer config: %+v", cfg.OpenAI)
	}
}

func TestLoadEdge_OllamaContextSize(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "local"
    adapters:
      ollama:
        enabled: true
        base_url: "http://192.168.0.91:11434"
        context_size: 262144
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	ollama := cfg.Nodes[0].Adapters.Ollama
	if !ollama.Enabled {
		t.Fatal("expected ollama.enabled=true")
	}
	if ollama.BaseURL != "http://192.168.0.91:11434" || ollama.ContextSize != 262144 {
		t.Fatalf("unexpected ollama config: %+v", ollama)
	}
}

func TestLoadEdge_ConsoleSessionDefaults(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	if err := os.WriteFile(f, []byte("server:\n  listen: \"0.0.0.0:9090\"\n"), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.Console.SessionID != "default" {
		t.Fatalf("expected default session_id=%q, got %q", "default", cfg.Console.SessionID)
	}
	if cfg.Console.Background {
		t.Fatal("expected default background=false")
	}
}

func TestLoadEdge_ConsoleSessionOverride(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := "server:\n  listen: \"0.0.0.0:9090\"\nconsole:\n  session_id: \"worker-1\"\n  background: true\n"
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.Console.SessionID != "worker-1" {
		t.Fatalf("expected session_id=%q, got %q", "worker-1", cfg.Console.SessionID)
	}
	if !cfg.Console.Background {
		t.Fatal("expected background=true")
	}
}

func TestLoadEdge_ConsoleTimeoutOverride(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := "server:\n  listen: \"0.0.0.0:9090\"\nconsole:\n  timeout_sec: 45\n"
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.Console.TimeoutSec != 45 {
		t.Fatalf("expected timeout_sec=45, got %d", cfg.Console.TimeoutSec)
	}
}

func TestLoadEdge_ConsoleTargetOverride(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := "server:\n  listen: \"0.0.0.0:9090\"\nconsole:\n  target: \"codex\"\n"
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.Console.ResolveTarget() != "codex" {
		t.Fatalf("expected console.target to resolve to %q, got %q", "codex", cfg.Console.ResolveTarget())
	}
}

func TestLoadEdge_ConsoleTargetFallbackFromLegacyAgent(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := "server:\n  listen: \"0.0.0.0:9090\"\nconsole:\n  agent: \"codex\"\n"
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.Console.ResolveTarget() != "codex" {
		t.Fatalf("expected legacy console.agent fallback to resolve to %q, got %q", "codex", cfg.Console.ResolveTarget())
	}
}

func TestLoadEdge_ConsoleTargetFallbackFromLegacyModel(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := "server:\n  listen: \"0.0.0.0:9090\"\nconsole:\n  model: \"codex\"\n"
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.Console.ResolveTarget() != "codex" {
		t.Fatalf("expected legacy console.model fallback to resolve to %q, got %q", "codex", cfg.Console.ResolveTarget())
	}
}

func TestLoadEdge_CodexProfile(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "local"
    adapters:
      cli:
        enabled: true
        profiles:
          codex:
            command: "codex"
            output_format: "codex-json"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}

	if len(cfg.Nodes) == 0 {
		t.Fatal("expected 1 node")
	}
	codex, ok := cfg.Nodes[0].Adapters.CLI.Profiles["codex"]
	if !ok {
		t.Fatal("expected codex profile")
	}
	if codex.Command != "codex" || codex.OutputFormat != "codex-json" {
		t.Errorf("unexpected codex profile: %+v", codex)
	}
}

func TestLoadEdge_AntigravityProfile(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "local"
    adapters:
      cli:
        enabled: true
        profiles:
          antigravity:
            command: "agy"
            args:
              - "--dangerously-skip-permissions"
              - "--print-timeout"
              - "10m"
              - "--print"
            resume_args:
              - "--dangerously-skip-permissions"
              - "--print-timeout"
              - "10m"
              - "--conversation"
            mode: "antigravity-print"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}

	if len(cfg.Nodes) == 0 {
		t.Fatal("expected 1 node")
	}
	agy, ok := cfg.Nodes[0].Adapters.CLI.Profiles["antigravity"]
	if !ok {
		t.Fatal("expected antigravity profile")
	}
	if agy.Command != "agy" {
		t.Errorf("expected command agy, got %q", agy.Command)
	}
	expectedArgs := []string{"--dangerously-skip-permissions", "--print-timeout", "10m", "--print"}
	if len(agy.Args) != len(expectedArgs) {
		t.Fatalf("expected %d args, got %d: %v", len(expectedArgs), len(agy.Args), agy.Args)
	}
	for i, v := range expectedArgs {
		if agy.Args[i] != v {
			t.Errorf("args[%d]: expected %q, got %q", i, v, agy.Args[i])
		}
	}
	if agy.OutputFormat != "" {
		t.Errorf("expected empty output format, got %q", agy.OutputFormat)
	}
	if agy.Mode != "antigravity-print" {
		t.Errorf("expected mode antigravity-print, got %q", agy.Mode)
	}
	expectedResume := []string{"--dangerously-skip-permissions", "--print-timeout", "10m", "--conversation"}
	if len(agy.ResumeArgs) != len(expectedResume) {
		t.Fatalf("expected %d resume_args, got %d: %v", len(expectedResume), len(agy.ResumeArgs), agy.ResumeArgs)
	}
	for i, v := range expectedResume {
		if agy.ResumeArgs[i] != v {
			t.Errorf("resume_args[%d]: expected %q, got %q", i, v, agy.ResumeArgs[i])
		}
	}
}

func TestCLIProfileConf_CompletionMarkerUnmarshal(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "local"
    adapters:
      cli:
        enabled: true
        profiles:
          marker-test:
            command: "mycli"
            completion_marker:
              line: "<<END_OF_RESPONSE>>"
              regex: "^DONE \\d+$"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}

	if len(cfg.Nodes) == 0 {
		t.Fatal("expected 1 node")
	}
	profile, ok := cfg.Nodes[0].Adapters.CLI.Profiles["marker-test"]
	if !ok {
		t.Fatal("expected marker-test profile")
	}
	if profile.CompletionMarker.Line != "<<END_OF_RESPONSE>>" {
		t.Errorf("expected Line=%q, got %q", "<<END_OF_RESPONSE>>", profile.CompletionMarker.Line)
	}
	if profile.CompletionMarker.Regex != "^DONE \\d+$" {
		t.Errorf("expected Regex=%q, got %q", "^DONE \\d+$", profile.CompletionMarker.Regex)
	}
}

func TestCompletionMarkerConf_Empty(t *testing.T) {
	var empty config.CompletionMarkerConf
	if !empty.Empty() {
		t.Fatal("expected Empty() == true for zero value")
	}

	lineOnly := config.CompletionMarkerConf{Line: "<<END>>"}
	if lineOnly.Empty() {
		t.Fatal("expected Empty() == false when Line is set")
	}

	regexOnly := config.CompletionMarkerConf{Regex: "^END$"}
	if regexOnly.Empty() {
		t.Fatal("expected Empty() == false when Regex is set")
	}

	bothSet := config.CompletionMarkerConf{Line: "<<END>>", Regex: "^END$"}
	if bothSet.Empty() {
		t.Fatal("expected Empty() == false when both are set")
	}
}

func TestCompletionMarkerConf_LineOnlyUnmarshal(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "local"
    adapters:
      cli:
        enabled: true
        profiles:
          line-only:
            command: "mycli"
            completion_marker:
              line: "<<END>>"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}

	profile, ok := cfg.Nodes[0].Adapters.CLI.Profiles["line-only"]
	if !ok {
		t.Fatal("expected line-only profile")
	}
	if profile.CompletionMarker.Line != "<<END>>" {
		t.Errorf("expected Line=%q, got %q", "<<END>>", profile.CompletionMarker.Line)
	}
	if profile.CompletionMarker.Regex != "" {
		t.Errorf("expected empty Regex, got %q", profile.CompletionMarker.Regex)
	}
	if profile.CompletionMarker.Empty() {
		t.Fatal("expected Empty() == false when only Line is set")
	}
}

func TestCompletionMarkerConf_RegexOnlyUnmarshal(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "local"
    adapters:
      cli:
        enabled: true
        profiles:
          regex-only:
            command: "mycli"
            completion_marker:
              regex: "^DONE \\d+$"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}

	profile, ok := cfg.Nodes[0].Adapters.CLI.Profiles["regex-only"]
	if !ok {
		t.Fatal("expected regex-only profile")
	}
	if profile.CompletionMarker.Regex != "^DONE \\d+$" {
		t.Errorf("expected Regex=%q, got %q", "^DONE \\d+$", profile.CompletionMarker.Regex)
	}
	if profile.CompletionMarker.Line != "" {
		t.Errorf("expected empty Line, got %q", profile.CompletionMarker.Line)
	}
	if profile.CompletionMarker.Empty() {
		t.Fatal("expected Empty() == false when only Regex is set")
	}
}

func TestLoadEdge_CLIProfileMode(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "local"
    adapters:
      cli:
        enabled: true
        profiles:
          codex:
            command: "codex"
            args:
              - "exec"
              - "--json"
            resume_args:
              - "exec"
              - "resume"
              - "--json"
            mode: "codex-exec"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}

	if len(cfg.Nodes) == 0 {
		t.Fatal("expected 1 node")
	}
	profile, ok := cfg.Nodes[0].Adapters.CLI.Profiles["codex"]
	if !ok {
		t.Fatal("expected codex profile")
	}
	if profile.Mode != "codex-exec" {
		t.Errorf("expected mode=%q, got %q", "codex-exec", profile.Mode)
	}
	expectedResume := []string{"exec", "resume", "--json"}
	if len(profile.ResumeArgs) != len(expectedResume) {
		t.Fatalf("expected %d resume_args, got %d: %v", len(expectedResume), len(profile.ResumeArgs), profile.ResumeArgs)
	}
	for i, v := range expectedResume {
		if profile.ResumeArgs[i] != v {
			t.Errorf("resume_args[%d]: expected %q, got %q", i, v, profile.ResumeArgs[i])
		}
	}
}

func TestLoadEdge_OpencodeSSEProfile(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "local"
    adapters:
      cli:
        enabled: true
        profiles:
          opencode:
            command: "/usr/local/bin/opencode"
            args:
              - "--title"
              - "untitle"
              - "--model"
              - "ollama-dgx/qwen3.6:35b-a3b-bf16"
              - "--dangerously-skip-permissions"
            mode: "opencode-sse"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if len(cfg.Nodes) == 0 {
		t.Fatal("expected 1 node")
	}
	prof, ok := cfg.Nodes[0].Adapters.CLI.Profiles["opencode"]
	if !ok {
		t.Fatal("expected opencode profile")
	}
	if prof.Mode != "opencode-sse" {
		t.Errorf("mode: got %q", prof.Mode)
	}
	expectedArgs := []string{"--title", "untitle", "--model", "ollama-dgx/qwen3.6:35b-a3b-bf16", "--dangerously-skip-permissions"}
	if len(prof.Args) != len(expectedArgs) {
		t.Fatalf("args len: got %d, want %d", len(prof.Args), len(expectedArgs))
	}
	for i, want := range expectedArgs {
		if prof.Args[i] != want {
			t.Errorf("args[%d]: got %q, want %q", i, prof.Args[i], want)
		}
	}
}

func TestCLIProfileConf_CompletionMarkerEmpty(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "local"
    adapters:
      cli:
        enabled: true
        profiles:
          no-marker:
            command: "mycli"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}

	profile, ok := cfg.Nodes[0].Adapters.CLI.Profiles["no-marker"]
	if !ok {
		t.Fatal("expected no-marker profile")
	}
	if !profile.CompletionMarker.Empty() {
		t.Fatal("expected Empty() == true when completion_marker is not specified")
	}
}

func TestLoadEdge_AdvertiseHostAndArtifactDefaultsEmpty(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	if err := os.WriteFile(f, []byte("server:\n  listen: \"0.0.0.0:9090\"\n"), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.Server.AdvertiseHost != "" {
		t.Errorf("expected empty server.advertise_host by default, got %q", cfg.Server.AdvertiseHost)
	}
	if cfg.Bootstrap.ArtifactBaseURL != "" {
		t.Errorf("expected empty bootstrap.artifact_base_url by default, got %q", cfg.Bootstrap.ArtifactBaseURL)
	}
	if cfg.Logging.Path != "" {
		t.Errorf("expected empty logging.path by default, got %q", cfg.Logging.Path)
	}
}

func TestLoadEdge_AdvertiseHostAndArtifactExplicit(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `server:
  listen: "0.0.0.0:9090"
  advertise_host: "edge.example.test"
bootstrap:
  artifact_base_url: "http://edge.example.test:18080"
logging:
  path: "/var/log/iop/edge.log"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.Server.AdvertiseHost != "edge.example.test" {
		t.Errorf("server.advertise_host=%q", cfg.Server.AdvertiseHost)
	}
	if cfg.Bootstrap.ArtifactBaseURL != "http://edge.example.test:18080" {
		t.Errorf("bootstrap.artifact_base_url=%q", cfg.Bootstrap.ArtifactBaseURL)
	}
	if cfg.Logging.Path != "/var/log/iop/edge.log" {
		t.Errorf("logging.path=%q", cfg.Logging.Path)
	}
}

func TestLoadEdge_A2ADefaults(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	if err := os.WriteFile(f, []byte("server:\n  listen: \"0.0.0.0:9090\"\n"), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.A2A.Enabled {
		t.Fatal("expected a2a.enabled=false by default")
	}
	if cfg.A2A.Listen != "0.0.0.0:8081" {
		t.Fatalf("expected a2a.listen default, got %q", cfg.A2A.Listen)
	}
	if cfg.A2A.Path != "/a2a" {
		t.Fatalf("expected a2a.path=%q, got %q", "/a2a", cfg.A2A.Path)
	}
	if cfg.A2A.Adapter != "cli" {
		t.Fatalf("expected a2a.adapter=%q, got %q", "cli", cfg.A2A.Adapter)
	}
	if cfg.A2A.SessionID != "a2a" {
		t.Fatalf("expected a2a.session_id=%q, got %q", "a2a", cfg.A2A.SessionID)
	}
	if cfg.A2A.TimeoutSec != 120 {
		t.Fatalf("expected a2a.timeout_sec=120, got %d", cfg.A2A.TimeoutSec)
	}
	if cfg.A2A.BearerToken != "" {
		t.Fatalf("expected a2a.bearer_token empty by default, got %q", cfg.A2A.BearerToken)
	}
}

func TestCompletionMarkerConf_RegexAndLineUsage(t *testing.T) {
	lineOnly := config.CompletionMarkerConf{Line: "<<END>>"}
	if !strings.Contains(lineOnly.Line, "<<END>>") {
		t.Errorf("expected Line to contain <<END>>, got %q", lineOnly.Line)
	}

	regexOnly := config.CompletionMarkerConf{Regex: "^DONE \\d+$"}
	if !strings.Contains(regexOnly.Regex, "DONE") {
		t.Errorf("expected Regex to contain DONE, got %q", regexOnly.Regex)
	}

	both := config.CompletionMarkerConf{Line: "<<END>>", Regex: "^DONE \\d+$"}
	if both.Line != "<<END>>" || both.Regex != "^DONE \\d+$" {
		t.Errorf("expected both fields set, got %+v", both)
	}
	if both.Empty() {
		t.Fatal("expected Empty() == false when both are set")
	}
}

func TestLoadEdge_A2AOverride(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
a2a:
  enabled: true
  listen: "127.0.0.1:8082"
  path: "/agent"
  node: "node0"
  adapter: "cli"
  target: "claude"
  session_id: "nomad"
  timeout_sec: 60
  bearer_token: "secret-token"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if !cfg.A2A.Enabled {
		t.Fatal("expected a2a.enabled=true")
	}
	if cfg.A2A.Listen != "127.0.0.1:8082" {
		t.Fatalf("expected a2a.listen=%q, got %q", "127.0.0.1:8082", cfg.A2A.Listen)
	}
	if cfg.A2A.Path != "/agent" {
		t.Fatalf("expected a2a.path=%q, got %q", "/agent", cfg.A2A.Path)
	}
	if cfg.A2A.NodeRef != "node0" {
		t.Fatalf("expected a2a.node=%q, got %q", "node0", cfg.A2A.NodeRef)
	}
	if cfg.A2A.Target != "claude" {
		t.Fatalf("expected a2a.target=%q, got %q", "claude", cfg.A2A.Target)
	}
	if cfg.A2A.SessionID != "nomad" {
		t.Fatalf("expected a2a.session_id=%q, got %q", "nomad", cfg.A2A.SessionID)
	}
	if cfg.A2A.TimeoutSec != 60 {
		t.Fatalf("expected a2a.timeout_sec=60, got %d", cfg.A2A.TimeoutSec)
	}
	if cfg.A2A.BearerToken != "secret-token" {
		t.Fatalf("expected a2a.bearer_token=%q, got %q", "secret-token", cfg.A2A.BearerToken)
	}
}

func TestLoadEdge_NodeAgentKindGeneric(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "node-local"
    token: "token-node"
    agent_kind: "generic-node"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if len(cfg.Nodes) == 0 {
		t.Fatal("expected 1 node")
	}
	if cfg.Nodes[0].AgentKind != config.AgentKindGenericNode {
		t.Fatalf("expected agent_kind=%q, got %q", config.AgentKindGenericNode, cfg.Nodes[0].AgentKind)
	}
}

func TestLoadEdge_NodeAgentKindDefault(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "node-local"
    token: "token-node"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if len(cfg.Nodes) == 0 {
		t.Fatal("expected 1 node")
	}
	if cfg.Nodes[0].AgentKind != config.AgentKindGenericNode {
		t.Fatalf("expected default agent_kind=%q, got %q", config.AgentKindGenericNode, cfg.Nodes[0].AgentKind)
	}
}

func TestLoadEdge_NodeAgentKindRejectsInvalid(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "bad-local"
    token: "token-bad"
    agent_kind: "not-a-kind"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	_, err := config.LoadEdge(f)
	if err == nil {
		t.Fatal("expected invalid agent_kind error")
	}
	if !strings.Contains(err.Error(), "agent_kind") {
		t.Fatalf("expected error to mention agent_kind, got %v", err)
	}
}

func TestLoadEdge_ControlPlaneDefaults(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	if err := os.WriteFile(f, []byte("server:\n  listen: \"0.0.0.0:9090\"\n"), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if cfg.ControlPlane.Enabled {
		t.Fatal("expected control_plane.enabled=false by default")
	}
	if cfg.ControlPlane.WireAddr != "" {
		t.Fatalf("expected control_plane.wire_addr empty by default, got %q", cfg.ControlPlane.WireAddr)
	}
	if cfg.ControlPlane.ReconnectIntervalSec != 5 {
		t.Fatalf("expected control_plane.reconnect_interval_sec=5, got %d", cfg.ControlPlane.ReconnectIntervalSec)
	}
}

func TestLoadEdge_MultiOllamaInstances(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "multi"
    adapters:
      ollama_instances:
        - name: "local"
          enabled: true
          base_url: "http://127.0.0.1:11434"
          context_size: 131072
        - name: "dgx"
          enabled: true
          base_url: "http://192.168.0.91:11434"
          context_size: 262144
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if len(cfg.Nodes) == 0 {
		t.Fatal("expected 1 node")
	}
	insts := cfg.Nodes[0].Adapters.OllamaInstances
	if len(insts) != 2 {
		t.Fatalf("expected 2 ollama instances, got %d", len(insts))
	}
	if insts[0].Name != "local" || insts[0].BaseURL != "http://127.0.0.1:11434" || insts[0].ContextSize != 131072 {
		t.Errorf("unexpected instance[0]: %+v", insts[0])
	}
	if insts[1].Name != "dgx" || insts[1].BaseURL != "http://192.168.0.91:11434" || insts[1].ContextSize != 262144 {
		t.Errorf("unexpected instance[1]: %+v", insts[1])
	}
}

func TestLoadEdge_MultiVllmInstances(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "multi-vllm"
    adapters:
      vllm_instances:
        - name: "a100"
          enabled: true
          endpoint: "http://10.0.0.5:8000"
        - name: "h100"
          enabled: true
          endpoint: "http://10.0.0.6:8000"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if len(cfg.Nodes) == 0 {
		t.Fatal("expected 1 node")
	}
	insts := cfg.Nodes[0].Adapters.VllmInstances
	if len(insts) != 2 {
		t.Fatalf("expected 2 vllm instances, got %d", len(insts))
	}
	if insts[0].Name != "a100" || insts[0].Endpoint != "http://10.0.0.5:8000" {
		t.Errorf("unexpected instance[0]: %+v", insts[0])
	}
	if insts[1].Name != "h100" || insts[1].Endpoint != "http://10.0.0.6:8000" {
		t.Errorf("unexpected instance[1]: %+v", insts[1])
	}
}

func TestLoadEdge_LegacyOllamaPromotedToInstances(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "local"
    adapters:
      ollama:
        enabled: true
        base_url: "http://192.168.0.91:11434"
        context_size: 262144
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	insts := cfg.Nodes[0].Adapters.OllamaInstances
	if len(insts) != 1 {
		t.Fatalf("expected 1 ollama instance from legacy field, got %d", len(insts))
	}
	if insts[0].Name != "ollama" {
		t.Errorf("expected instance name %q, got %q", "ollama", insts[0].Name)
	}
	if insts[0].BaseURL != "http://192.168.0.91:11434" {
		t.Errorf("expected base_url %q, got %q", "http://192.168.0.91:11434", insts[0].BaseURL)
	}
}

func TestLoadEdge_DuplicateOllamaInstanceNameRejected(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "dup"
    adapters:
      ollama_instances:
        - name: "same"
          enabled: true
          base_url: "http://127.0.0.1:11434"
        - name: "same"
          enabled: true
          base_url: "http://127.0.0.2:11434"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	_, err := config.LoadEdge(f)
	if err == nil {
		t.Fatal("expected error for duplicate ollama instance name")
	}
}

func TestLoadEdge_OpenAIRouteCatalog(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
openai:
  enabled: true
  listen: "0.0.0.0:18081"
  adapter: "ollama"
  model_routes:
    - model: "model-a"
      adapter: "ollama"
      target: "llama3"
      node: "node-01"
      session_id: "sess-a"
      timeout_sec: 30
    - model: "model-b"
      adapter: "vllm"
      target: "qwen"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if len(cfg.OpenAI.ModelRoutes) != 2 {
		t.Fatalf("expected 2 model_routes, got %d", len(cfg.OpenAI.ModelRoutes))
	}
	r0 := cfg.OpenAI.ModelRoutes[0]
	if r0.Model != "model-a" || r0.Adapter != "ollama" || r0.Target != "llama3" {
		t.Errorf("route[0] mismatch: %+v", r0)
	}
	if r0.NodeRef != "node-01" || r0.SessionID != "sess-a" || r0.TimeoutSec != 30 {
		t.Errorf("route[0] optional fields mismatch: %+v", r0)
	}
	if r0.WorkspaceRequired {
		t.Errorf("route[0] workspace_required should default to false: %+v", r0)
	}
	r1 := cfg.OpenAI.ModelRoutes[1]
	if r1.Model != "model-b" || r1.Adapter != "vllm" || r1.Target != "qwen" {
		t.Errorf("route[1] mismatch: %+v", r1)
	}
	if r1.WorkspaceRequired {
		t.Errorf("route[1] workspace_required should default to false: %+v", r1)
	}
}

func TestLoadEdge_OpenAIRouteCatalogWorkspaceRequired(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
openai:
  enabled: true
  model_routes:
    - model: "codex"
      adapter: "cli"
      target: "codex"
      workspace_required: true
    - model: "llama3"
      adapter: "ollama"
      target: "llama3:8b"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if len(cfg.OpenAI.ModelRoutes) != 2 {
		t.Fatalf("expected 2 model_routes, got %d", len(cfg.OpenAI.ModelRoutes))
	}
	agent := cfg.OpenAI.ModelRoutes[0]
	if agent.Model != "codex" || agent.Adapter != "cli" || agent.Target != "codex" {
		t.Errorf("agent route mismatch: %+v", agent)
	}
	if !agent.WorkspaceRequired {
		t.Errorf("agent route workspace_required should be true: %+v", agent)
	}
	inference := cfg.OpenAI.ModelRoutes[1]
	if inference.Model != "llama3" || inference.Adapter != "ollama" || inference.Target != "llama3:8b" {
		t.Errorf("inference route mismatch: %+v", inference)
	}
	if inference.WorkspaceRequired {
		t.Errorf("inference route workspace_required should be false: %+v", inference)
	}
}

func TestLoadEdge_OpenAIRouteCatalogDuplicateModelRejects(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
openai:
  model_routes:
    - model: "model-a"
      adapter: "ollama"
      target: "llama3"
    - model: "model-a"
      adapter: "vllm"
      target: "qwen"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	_, err := config.LoadEdge(f)
	if err == nil {
		t.Fatal("expected error for duplicate model route")
	}
	if !strings.Contains(err.Error(), "model_routes") || !strings.Contains(err.Error(), "model-a") {
		t.Fatalf("expected error mentioning model_routes and model-a, got %v", err)
	}
}

func TestLoadEdge_OpenAIRouteCatalogEmptyModelRejects(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
openai:
  model_routes:
    - model: ""
      target: "llama3"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	_, err := config.LoadEdge(f)
	if err == nil {
		t.Fatal("expected error for empty model in route catalog")
	}
	if !strings.Contains(err.Error(), "model_routes") {
		t.Fatalf("expected error mentioning model_routes, got %v", err)
	}
}

// NormalizeAdapters regression tests

func TestNormalizeAdapters_OllamaIdempotent(t *testing.T) {
	a := config.AdaptersConf{
		Ollama: config.OllamaConf{Enabled: true, BaseURL: "http://127.0.0.1:11434", ContextSize: 4096},
	}
	if err := config.NormalizeAdapters(&a); err != nil {
		t.Fatalf("first normalize: %v", err)
	}
	if len(a.OllamaInstances) != 1 {
		t.Fatalf("expected 1 instance after first normalize, got %d", len(a.OllamaInstances))
	}
	if err := config.NormalizeAdapters(&a); err != nil {
		t.Fatalf("second normalize (idempotent): %v", err)
	}
	if len(a.OllamaInstances) != 1 {
		t.Fatalf("expected still 1 instance after second normalize, got %d", len(a.OllamaInstances))
	}
}

func TestNormalizeAdapters_VllmIdempotent(t *testing.T) {
	a := config.AdaptersConf{
		Vllm: config.VllmConf{Enabled: true, Endpoint: "http://127.0.0.1:8000"},
	}
	if err := config.NormalizeAdapters(&a); err != nil {
		t.Fatalf("first normalize: %v", err)
	}
	if len(a.VllmInstances) != 1 {
		t.Fatalf("expected 1 instance after first normalize, got %d", len(a.VllmInstances))
	}
	if err := config.NormalizeAdapters(&a); err != nil {
		t.Fatalf("second normalize (idempotent): %v", err)
	}
	if len(a.VllmInstances) != 1 {
		t.Fatalf("expected still 1 instance after second normalize, got %d", len(a.VllmInstances))
	}
}

func TestNormalizeAdapters_OllamaConflictErrors(t *testing.T) {
	a := config.AdaptersConf{
		Ollama: config.OllamaConf{Enabled: true, BaseURL: "http://127.0.0.1:11434"},
		OllamaInstances: []config.OllamaInstanceConf{
			{Name: "ollama", Enabled: true, BaseURL: "http://other-host:11434"},
		},
	}
	if err := config.NormalizeAdapters(&a); err == nil {
		t.Fatal("expected error for conflicting legacy ollama and explicit instance with same name")
	}
}

func TestNormalizeAdapters_VllmConflictErrors(t *testing.T) {
	a := config.AdaptersConf{
		Vllm: config.VllmConf{Enabled: true, Endpoint: "http://127.0.0.1:8000"},
		VllmInstances: []config.VllmInstanceConf{
			{Name: "vllm", Enabled: true, Endpoint: "http://other-host:8000"},
		},
	}
	if err := config.NormalizeAdapters(&a); err == nil {
		t.Fatal("expected error for conflicting legacy vllm and explicit instance with same name")
	}
}

func TestNormalizeAdapters_OllamaDisabledSameNameErrors(t *testing.T) {
	a := config.AdaptersConf{
		Ollama: config.OllamaConf{Enabled: true, BaseURL: "http://127.0.0.1:11434"},
		OllamaInstances: []config.OllamaInstanceConf{
			{Name: "ollama", Enabled: false, BaseURL: "http://127.0.0.1:11434"},
		},
	}
	if err := config.NormalizeAdapters(&a); err == nil {
		t.Fatal("expected error for legacy enabled ollama conflicting with same-name disabled explicit instance")
	}
}

func TestNormalizeAdapters_VllmDisabledSameNameErrors(t *testing.T) {
	a := config.AdaptersConf{
		Vllm: config.VllmConf{Enabled: true, Endpoint: "http://127.0.0.1:8000"},
		VllmInstances: []config.VllmInstanceConf{
			{Name: "vllm", Enabled: false, Endpoint: "http://127.0.0.1:8000"},
		},
	}
	if err := config.NormalizeAdapters(&a); err == nil {
		t.Fatal("expected error for legacy enabled vllm conflicting with same-name disabled explicit instance")
	}
}

func TestLoadEdge_CodexAppServerDefaultProfile(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
nodes:
  - alias: "local"
    adapters:
      cli:
        enabled: true
        profiles:
          codex:
            command: "codex"
            args:
              - "app-server"
            mode: "codex-app-server"
          codex-exec:
            command: "codex"
            args:
              - "exec"
              - "--json"
            resume_args:
              - "exec"
              - "resume"
              - "--json"
            output_format: "codex-json"
            mode: "codex-exec"
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}

	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}

	if len(cfg.Nodes) == 0 {
		t.Fatal("expected 1 node")
	}
	profiles := cfg.Nodes[0].Adapters.CLI.Profiles

	codex, ok := profiles["codex"]
	if !ok {
		t.Fatal("expected codex profile")
	}
	if codex.Mode != "codex-app-server" {
		t.Errorf("codex.Mode = %q, want %q", codex.Mode, "codex-app-server")
	}
	if len(codex.Args) != 1 || codex.Args[0] != "app-server" {
		t.Errorf("codex.Args = %v, want [app-server]", codex.Args)
	}

	exec, ok := profiles["codex-exec"]
	if !ok {
		t.Fatal("expected codex-exec profile")
	}
	if exec.Mode != "codex-exec" {
		t.Errorf("codex-exec.Mode = %q, want %q", exec.Mode, "codex-exec")
	}
	if exec.OutputFormat != "codex-json" {
		t.Errorf("codex-exec.OutputFormat = %q, want %q", exec.OutputFormat, "codex-json")
	}
	expectedResume := []string{"exec", "resume", "--json"}
	if len(exec.ResumeArgs) != len(expectedResume) {
		t.Fatalf("codex-exec.ResumeArgs = %v, want %v", exec.ResumeArgs, expectedResume)
	}
	for i, v := range expectedResume {
		if exec.ResumeArgs[i] != v {
			t.Errorf("codex-exec.ResumeArgs[%d] = %q, want %q", i, exec.ResumeArgs[i], v)
		}
	}
}

func TestLoadEdge_ControlPlaneOverride(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "edge.yaml")
	yaml := `
server:
  listen: "0.0.0.0:9090"
control_plane:
  enabled: true
  wire_addr: "cp.example.test:7070"
  reconnect_interval_sec: 10
`
	if err := os.WriteFile(f, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write yaml: %v", err)
	}
	cfg, err := config.LoadEdge(f)
	if err != nil {
		t.Fatalf("load: %v", err)
	}
	if !cfg.ControlPlane.Enabled {
		t.Fatal("expected control_plane.enabled=true")
	}
	if cfg.ControlPlane.WireAddr != "cp.example.test:7070" {
		t.Fatalf("expected control_plane.wire_addr=%q, got %q", "cp.example.test:7070", cfg.ControlPlane.WireAddr)
	}
	if cfg.ControlPlane.ReconnectIntervalSec != 10 {
		t.Fatalf("expected control_plane.reconnect_interval_sec=10, got %d", cfg.ControlPlane.ReconnectIntervalSec)
	}
}
