// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
//
// SPDX-License-Identifier: LicenseRef-MutuaL-1.2

package appconfig

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

	"git.secluded.site/cooked-mcp/internal/configvalue"
)

func TestLoadACIDAuthenticationCredentials21ResolvesTOMLConfigValues(t *testing.T) {
	t.Setenv("COOKED_USERNAME_FROM_MY_SHELL", "shell-user")

	configPath := filepath.Join(t.TempDir(), "config.toml")
	writeConfig(t, configPath, `[user]
name = "$COOKED_USERNAME_FROM_MY_SHELL"
password = "!printf shell-password"
`)

	got, err := Load(context.Background(), configPath, configvalue.NewResolver())
	if err != nil {
		t.Fatalf("Load() error = %v", err)
	}

	if got.Username != "shell-user" {
		t.Fatalf("Username = %q, want shell-user", got.Username)
	}
	if got.Password != "shell-password" {
		t.Fatalf("Password = %q, want shell-password", got.Password)
	}
}

func TestLoadACIDAuthenticationCredentials11EnvironmentOverridesTOML(t *testing.T) {
	t.Setenv("COOKED_LOGIN_USERNAME", "override-user")
	t.Setenv("COOKED_LOGIN_PASSWORD", "override-password")

	configPath := filepath.Join(t.TempDir(), "config.toml")
	writeConfig(t, configPath, `[user]
name = "toml-user"
password = "toml-password"
`)

	got, err := Load(context.Background(), configPath, configvalue.NewResolver())
	if err != nil {
		t.Fatalf("Load() error = %v", err)
	}

	if got.Username != "override-user" {
		t.Fatalf("Username = %q, want override-user", got.Username)
	}
	if got.Password != "override-password" {
		t.Fatalf("Password = %q, want override-password", got.Password)
	}
}

func TestLoadRejectsMissingExplicitConfigFile(t *testing.T) {
	_, err := Load(context.Background(), filepath.Join(t.TempDir(), "missing.toml"), configvalue.NewResolver())
	if err == nil {
		t.Fatal("Load() error = nil, want missing config error")
	}
}

func TestLoadACIDServerConfig72RejectsMissingDefaultConfigHome(t *testing.T) {
	t.Setenv("XDG_CONFIG_HOME", "")

	originalUserHomeDir := userHomeDir
	userHomeDir = func() (string, error) {
		return "", os.ErrNotExist
	}
	t.Cleanup(func() {
		userHomeDir = originalUserHomeDir
	})

	_, err := Load(context.Background(), "", configvalue.NewResolver())
	if err == nil {
		t.Fatal("Load() error = nil, want default config path error")
	}
	if !strings.Contains(err.Error(), "resolve default config path") {
		t.Fatalf("Load() error = %v, want default config path error", err)
	}
}

func TestLoadRejectsNonLocalHTTPBaseURL(t *testing.T) {
	configPath := filepath.Join(t.TempDir(), "config.toml")
	writeConfig(t, configPath, `[user]
name = "toml-user"
password = "toml-password"

[cooked]
base_url = "http://example.com"
`)

	_, err := Load(context.Background(), configPath, configvalue.NewResolver())
	if err == nil {
		t.Fatal("Load() error = nil, want non-local HTTP base URL error")
	}
	if !strings.Contains(err.Error(), "must use https") {
		t.Fatalf("Load() error = %v, want https error", err)
	}
}

func writeConfig(t *testing.T, path, content string) {
	t.Helper()

	if err := os.WriteFile(path, []byte(content), 0o600); err != nil {
		t.Fatalf("write config: %v", err)
	}
}
