package config

import (
	"testing"
)

func TestHasEnvSource(t *testing.T) {
	tests := []struct {
		name    string
		environ map[string]string
		envKey  string
		procEnv map[string]string // simulated process env
		want    bool
	}{
		{
			name:    "direct key present",
			environ: map[string]string{"RESTIC_REPOSITORY": "s3:bucket"},
			envKey:  "RESTIC_REPOSITORY",
			want:    true,
		},
		{
			name:    "command variant present",
			environ: map[string]string{"RESTIC_REPOSITORY_COMMAND": "op read ..."},
			envKey:  "RESTIC_REPOSITORY",
			want:    true,
		},
		{
			name:    "neither direct nor command",
			environ: map[string]string{"OTHER_VAR": "value"},
			envKey:  "RESTIC_REPOSITORY",
			want:    false,
		},
		{
			name:    "nil environ",
			environ: nil,
			envKey:  "RESTIC_REPOSITORY",
			want:    false,
		},
		{
			name:    "empty string value counts as absent",
			environ: map[string]string{"RESTIC_REPOSITORY": ""},
			envKey:  "RESTIC_REPOSITORY",
			want:    false,
		},
		{
			name:    "command variant for non-restic key",
			environ: map[string]string{"AWS_ACCESS_KEY_ID_COMMAND": "op read ..."},
			envKey:  "AWS_ACCESS_KEY_ID",
			want:    true,
		},
		{
			name:    "process env fallback",
			environ: nil,
			envKey:  "KELD_TEST_HAS_ENV_SOURCE",
			procEnv: map[string]string{"KELD_TEST_HAS_ENV_SOURCE": "from-process"},
			want:    true,
		},
		{
			name:    "process env empty when not set",
			environ: nil,
			envKey:  "KELD_TEST_HAS_ENV_SOURCE",
			want:    false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Tests using t.Setenv cannot run in parallel.
			if len(tt.procEnv) == 0 {
				t.Parallel()
			}

			for k, v := range tt.procEnv {
				t.Setenv(k, v)
			}

			cfg := &ResolvedConfig{
				Environ: tt.environ,
			}

			got := cfg.HasEnvSource(tt.envKey)
			if got != tt.want {
				t.Errorf("HasEnvSource(%q) = %v, want %v", tt.envKey, got, tt.want)
			}
		})
	}
}
