package config_test

import (
	"errors"
	"os"
	"path/filepath"
	"testing"
	"time"

	"git.vakhrushev.me/av/healthlog/internal/config"
)

// Отсутствующий конфиг — не ошибка: локальный запуск должен работать «из
// коробки», без файла.
func TestLoadMissingFileUsesDefaults(t *testing.T) {
	cfg, err := config.Load(filepath.Join(t.TempDir(), "нет-такого.toml"))
	if err != nil {
		t.Fatalf("Load: %v", err)
	}

	if cfg.Server.Addr != ":8080" {
		t.Errorf("addr = %q, ожидалось \":8080\"", cfg.Server.Addr)
	}
	if cfg.Ingest.MaxBodyMB != 64 {
		t.Errorf("max_body_mb = %d, ожидалось 64", cfg.Ingest.MaxBodyMB)
	}
	if cfg.Server.ReadTimeout.D() != 5*time.Minute {
		t.Errorf("read_timeout = %v, ожидалось 5m", cfg.Server.ReadTimeout.D())
	}
	if len(cfg.Auth.WriteTokens) != 0 {
		t.Errorf("write_tokens = %v, ожидался пустой список", cfg.Auth.WriteTokens)
	}
}

func TestLoadReadsFile(t *testing.T) {
	path := writeConfig(t, `
[server]
addr = "127.0.0.1:9000"
read_timeout = "1m"

[auth]
write_tokens = ["секрет"]

[ingest]
max_body_mb = 8

[log]
level = "debug"
format = "text"
`)

	cfg, err := config.Load(path)
	if err != nil {
		t.Fatalf("Load: %v", err)
	}

	if cfg.Server.Addr != "127.0.0.1:9000" {
		t.Errorf("addr = %q", cfg.Server.Addr)
	}
	if cfg.Server.ReadTimeout.D() != time.Minute {
		t.Errorf("read_timeout = %v", cfg.Server.ReadTimeout.D())
	}
	if cfg.Ingest.MaxBodyMB != 8 {
		t.Errorf("max_body_mb = %d", cfg.Ingest.MaxBodyMB)
	}
	if len(cfg.Auth.WriteTokens) != 1 || cfg.Auth.WriteTokens[0] != "секрет" {
		t.Errorf("write_tokens = %v", cfg.Auth.WriteTokens)
	}
}

// Валидация собирает все проблемы разом (errors.Join), а не чинится по одной
// за перезапуск.
func TestValidateReportsAllProblems(t *testing.T) {
	path := writeConfig(t, `
[ingest]
max_body_mb = -1

[auth]
write_tokens = ["  "]

[log]
level = "нет-такого"
format = "yaml"
`)

	_, err := config.Load(path)
	if err == nil {
		t.Fatal("ожидалась ошибка валидации")
	}

	for _, want := range []error{config.ErrOutOfRange, config.ErrUnknownValue, config.ErrEmptyToken} {
		if !errors.Is(err, want) {
			t.Errorf("ошибка не содержит %v: %v", want, err)
		}
	}
}

func TestLoadRejectsBrokenTOML(t *testing.T) {
	if _, err := config.Load(writeConfig(t, "это не toml =")); err == nil {
		t.Fatal("ожидалась ошибка разбора")
	}
}

func writeConfig(t *testing.T, body string) string {
	t.Helper()
	path := filepath.Join(t.TempDir(), "config.toml")
	if err := os.WriteFile(path, []byte(body), 0o600); err != nil {
		t.Fatalf("подготовка конфига: %v", err)
	}
	return path
}
