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

package configvalue

import (
	"context"
	"runtime"
	"testing"
	"time"
)

func TestResolveACIDConfigValuesResolution1InterpolatesEnvironment(t *testing.T) {
	t.Setenv("COOKED_USERNAME_FROM_MY_SHELL", "ada")
	t.Setenv("COOKED_SUFFIX", "lovelace")

	tests := []struct {
		name   string
		config string
		want   string
	}{
		{name: "plain literal", config: "literal", want: "literal"},
		{name: "dollar prefix", config: "$COOKED_USERNAME_FROM_MY_SHELL", want: "ada"},
		{name: "braced reference", config: "${COOKED_USERNAME_FROM_MY_SHELL}-${COOKED_SUFFIX}", want: "ada-lovelace"},
		{name: "escaped dollar and bang", config: "$$$COOKED_USERNAME_FROM_MY_SHELL$!", want: "$ada!"},
	}

	resolver := NewResolver()
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, ok := resolver.Resolve(context.Background(), tt.config)
			if !ok {
				t.Fatalf("Resolve(%q) ok = false", tt.config)
			}

			if got != tt.want {
				t.Fatalf("Resolve(%q) = %q, want %q", tt.config, got, tt.want)
			}
		})
	}
}

func TestResolveACIDConfigValuesResolution1RejectsMissingEnvironment(t *testing.T) {
	resolver := NewResolver()

	got, ok := resolver.Resolve(context.Background(), "$COOKED_MISSING_VALUE")
	if ok {
		t.Fatalf("Resolve ok = true, got %q", got)
	}
}

func TestResolveACIDConfigValuesCommands3CachesCommandResults(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skip("shell command syntax is POSIX-specific")
	}

	resolver := NewResolver()
	command := "!printf cooked"

	first, ok := resolver.Resolve(context.Background(), command)
	if !ok {
		t.Fatal("first command resolution failed")
	}

	second, ok := resolver.Resolve(context.Background(), command)
	if !ok {
		t.Fatal("second command resolution failed")
	}

	if first != "cooked" || second != "cooked" {
		t.Fatalf("resolved command values = %q and %q, want cooked", first, second)
	}

	resolver.CommandTimeout = time.Nanosecond
	third, ok := resolver.Resolve(context.Background(), command)
	if !ok || third != "cooked" {
		t.Fatalf("cached command value = %q, %v; want cooked, true", third, ok)
	}
}
