package platform

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

// withTempFile points the package-level path variable at a temp file
// containing the given content for the duration of the test.
func withTempFile(t *testing.T, target *string, content string) {
	t.Helper()
	dir := t.TempDir()
	path := filepath.Join(dir, "fake")
	if err := os.WriteFile(path, []byte(content), 0o600); err != nil {
		t.Fatalf("write temp file: %v", err)
	}
	original := *target
	*target = path
	t.Cleanup(func() { *target = original })
}

func TestIsWSL_DetectsMicrosoftToken(t *testing.T) {
	if runtime.GOOS != "linux" {
		t.Skip("IsWSL only meaningful on linux")
	}
	withTempFile(t, &procVersionPath,
		"Linux version 5.15.146.1-microsoft-standard-WSL2 (root@build) "+
			"(gcc (GCC) 11.2.0) #1 SMP Thu Jan 11 04:09:03 UTC 2026\n")
	if !IsWSL() {
		t.Errorf("expected IsWSL to recognize Microsoft kernel string")
	}
}

func TestIsWSL_DetectsWslToken(t *testing.T) {
	if runtime.GOOS != "linux" {
		t.Skip("IsWSL only meaningful on linux")
	}
	withTempFile(t, &procVersionPath,
		"Linux version 6.6.0 wsl ... \n")
	if !IsWSL() {
		t.Errorf("expected IsWSL to recognize lowercase WSL token")
	}
}

func TestIsWSL_NativeLinuxReturnsFalse(t *testing.T) {
	if runtime.GOOS != "linux" {
		t.Skip("IsWSL only meaningful on linux")
	}
	withTempFile(t, &procVersionPath,
		"Linux version 6.8.0-40-generic (buildd@lcy02-amd64-027) "+
			"(x86_64-linux-gnu-gcc-13 (Ubuntu 13.2.0-23ubuntu4) 13.2.0)\n")
	if IsWSL() {
		t.Errorf("expected IsWSL to be false on native Linux kernel string")
	}
}

func TestIsWSL_MissingFileReturnsFalse(t *testing.T) {
	if runtime.GOOS != "linux" {
		t.Skip("IsWSL only meaningful on linux")
	}
	original := procVersionPath
	procVersionPath = filepath.Join(t.TempDir(), "does-not-exist")
	t.Cleanup(func() { procVersionPath = original })
	if IsWSL() {
		t.Errorf("expected IsWSL to be false when /proc/version is unreadable")
	}
}

func TestWSLHostIP_FirstNameserver(t *testing.T) {
	withTempFile(t, &resolvConfPath,
		"# Generated by WSL\n"+
			"nameserver 172.29.176.1\n"+
			"nameserver 8.8.8.8\n")
	if got := WSLHostIP(); got != "172.29.176.1" {
		t.Errorf("expected 172.29.176.1, got %q", got)
	}
}

func TestWSLHostIP_IgnoresCommentsAndOptions(t *testing.T) {
	withTempFile(t, &resolvConfPath,
		"# WSL DNS forwarder\n"+
			"options edns0 trust-ad\n"+
			"search localdomain\n"+
			"nameserver 10.0.0.1\n")
	if got := WSLHostIP(); got != "10.0.0.1" {
		t.Errorf("expected 10.0.0.1, got %q", got)
	}
}

func TestWSLHostIP_MissingFileReturnsEmpty(t *testing.T) {
	original := resolvConfPath
	resolvConfPath = filepath.Join(t.TempDir(), "does-not-exist")
	t.Cleanup(func() { resolvConfPath = original })
	if got := WSLHostIP(); got != "" {
		t.Errorf("expected empty string when resolv.conf absent, got %q", got)
	}
}

func TestWSLHostIP_NoNameserverReturnsEmpty(t *testing.T) {
	withTempFile(t, &resolvConfPath,
		"# nothing useful here\n"+
			"options edns0\n")
	if got := WSLHostIP(); got != "" {
		t.Errorf("expected empty string when no nameserver line, got %q", got)
	}
}
