package workspace

import (
	"encoding/json"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
)

func TestChatOnly_NoApiKey_KeepsHome(t *testing.T) {
	t.Setenv("CURSOR_API_KEY", "")

	dir, env, err := ChatOnly("")
	if err != nil {
		t.Fatalf("ChatOnly: %v", err)
	}
	t.Cleanup(func() { _ = os.RemoveAll(dir) })

	if !filepath.IsAbs(dir) {
		t.Errorf("expected absolute path, got %q", dir)
	}

	cfgPath := filepath.Join(dir, ".cursor", "cli-config.json")
	data, err := os.ReadFile(cfgPath)
	if err != nil {
		t.Fatalf("expected cli-config.json to exist: %v", err)
	}
	var parsed map[string]any
	if err := json.Unmarshal(data, &parsed); err != nil {
		t.Fatalf("cli-config.json is not valid JSON: %v", err)
	}

	if env["CURSOR_CONFIG_DIR"] != filepath.Join(dir, ".cursor") {
		t.Errorf("CURSOR_CONFIG_DIR override wrong: %q", env["CURSOR_CONFIG_DIR"])
	}
	if _, ok := env["HOME"]; ok {
		t.Errorf("HOME should NOT be overridden without CURSOR_API_KEY, got %q (would break keychain auth)", env["HOME"])
	}
}

func TestChatOnly_WithApiKey_IsolatesHome(t *testing.T) {
	t.Setenv("CURSOR_API_KEY", "sk-fake-for-test")

	dir, env, err := ChatOnly("")
	if err != nil {
		t.Fatalf("ChatOnly: %v", err)
	}
	t.Cleanup(func() { _ = os.RemoveAll(dir) })

	if env["HOME"] != dir {
		t.Errorf("HOME override = %q, want %q", env["HOME"], dir)
	}
	if runtime.GOOS != "windows" && env["XDG_CONFIG_HOME"] != filepath.Join(dir, ".config") {
		t.Errorf("XDG_CONFIG_HOME override wrong: %q", env["XDG_CONFIG_HOME"])
	}
}

func TestChatOnly_WithAuthConfigDir_OnlySetsCursorConfigDir(t *testing.T) {
	dir, env, err := ChatOnly("/tmp/fake-auth")
	if err != nil {
		t.Fatalf("ChatOnly: %v", err)
	}
	t.Cleanup(func() { _ = os.RemoveAll(dir) })

	if env["CURSOR_CONFIG_DIR"] != "/tmp/fake-auth" {
		t.Errorf("expected CURSOR_CONFIG_DIR to be the auth dir, got %q", env["CURSOR_CONFIG_DIR"])
	}
	if _, ok := env["HOME"]; ok {
		t.Errorf("HOME should not be overridden when authConfigDir is set, got %q", env["HOME"])
	}
}

func TestMergeEnv_OverridesExistingKeys(t *testing.T) {
	base := []string{"FOO=1", "HOME=/old", "BAR=2"}
	out := MergeEnv(base, map[string]string{
		"HOME": "/new",
		"BAZ":  "3",
	})

	joined := strings.Join(out, "\n")
	if !strings.Contains(joined, "HOME=/new") {
		t.Errorf("expected HOME=/new in merged env, got: %v", out)
	}
	if strings.Contains(joined, "HOME=/old") {
		t.Errorf("old HOME should have been replaced, got: %v", out)
	}
	if !strings.Contains(joined, "FOO=1") || !strings.Contains(joined, "BAR=2") {
		t.Errorf("unchanged keys should pass through, got: %v", out)
	}
	if !strings.Contains(joined, "BAZ=3") {
		t.Errorf("new key should be appended, got: %v", out)
	}
}

func TestMergeEnv_EmptyOverridesReturnsSameSlice(t *testing.T) {
	base := []string{"FOO=1"}
	out := MergeEnv(base, nil)
	if len(out) != 1 || out[0] != "FOO=1" {
		t.Errorf("expected base unchanged, got %v", out)
	}
}
