package main

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

// TestResolveClusterPass verifies the secret resolution precedence
// (file > env > flag) that keeps the cluster password out of argv (issue 0006f).
func TestResolveClusterPass(t *testing.T) {
	// file wins over env and flag, and is trimmed.
	f := filepath.Join(t.TempDir(), "pass")
	if err := os.WriteFile(f, []byte("filesecret\n"), 0o600); err != nil {
		t.Fatalf("write: %v", err)
	}
	if got, src, err := resolveClusterPass("flagsecret", f, "envsecret"); err != nil || got != "filesecret" || src != "file" {
		t.Fatalf("file precedence: got %q src %q err %v", got, src, err)
	}
	// env wins over flag when no file.
	if got, src, err := resolveClusterPass("flagsecret", "", "envsecret"); err != nil || got != "envsecret" || src != "env" {
		t.Fatalf("env precedence: got %q src %q err %v", got, src, err)
	}
	// flag is the last resort.
	if got, src, err := resolveClusterPass("flagsecret", "", ""); err != nil || got != "flagsecret" || src != "flag" {
		t.Fatalf("flag fallback: got %q src %q err %v", got, src, err)
	}
	// none set.
	if got, src, err := resolveClusterPass("", "", ""); err != nil || got != "" || src != "none" {
		t.Fatalf("none: got %q src %q err %v", got, src, err)
	}
	// missing file is an error.
	if _, _, err := resolveClusterPass("", filepath.Join(t.TempDir(), "nope"), ""); err == nil {
		t.Fatalf("missing file must error")
	}
}

// TestInjectRouteCreds verifies the secret is injected only into routes that omit
// userinfo, so --routes argv need not carry the password (issue 0006f).
func TestInjectRouteCreds(t *testing.T) {
	in := []string{"nats://10.0.0.2:6250", "nats://override:pw@10.0.0.3:6250"}
	out, err := injectRouteCreds(in, "user", "secret")
	if err != nil {
		t.Fatalf("inject: %v", err)
	}
	if !strings.Contains(out[0], "user:secret@10.0.0.2:6250") {
		t.Fatalf("creds not injected into bare route: %q", out[0])
	}
	if !strings.Contains(out[1], "override:pw@10.0.0.3:6250") {
		t.Fatalf("existing userinfo must be preserved: %q", out[1])
	}
	// empty user is a no-op.
	noop, err := injectRouteCreds(in, "", "")
	if err != nil || noop[0] != in[0] {
		t.Fatalf("empty user must be a no-op: %v %q", err, noop[0])
	}
}

// TestIsLoopbackURL guards migrate-to-kv against pushing the allowlist cleartext
// to a remote NATS (issue 0006f, audit 0008 N6).
func TestIsLoopbackURL(t *testing.T) {
	loop := []string{"nats://127.0.0.1:4250", "nats://localhost:4250", "nats://[::1]:4250"}
	for _, u := range loop {
		if !isLoopbackURL(u) {
			t.Fatalf("%q should be loopback", u)
		}
	}
	remote := []string{"nats://10.0.0.2:4250", "nats://bus.example.com:4250", "::not-a-url"}
	for _, u := range remote {
		if isLoopbackURL(u) {
			t.Fatalf("%q should NOT be loopback", u)
		}
	}
}
