package osdetect

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

func TestParseID_Ubuntu(t *testing.T) {
	content := `NAME="Ubuntu"
VERSION="24.04.4 LTS (Noble Numbat)"
ID=ubuntu
ID_LIKE=debian`
	if got := ParseID([]byte(content)); got != "ubuntu" {
		t.Errorf("got %q, want ubuntu", got)
	}
}

func TestParseID_Debian(t *testing.T) {
	if got := ParseID([]byte("ID=debian\n")); got != "debian" {
		t.Errorf("got %q, want debian", got)
	}
}

func TestParseID_Alpine(t *testing.T) {
	if got := ParseID([]byte("ID=alpine\n")); got != "alpine" {
		t.Errorf("got %q, want alpine", got)
	}
}

func TestParseID_PVE(t *testing.T) {
	if got := ParseID([]byte("ID=pve\nID_LIKE=debian\n")); got != "pve" {
		t.Errorf("got %q, want pve", got)
	}
}

func TestParseID_QuotedValue(t *testing.T) {
	if got := ParseID([]byte(`ID="ubuntu"` + "\n")); got != "ubuntu" {
		t.Errorf("got %q, want ubuntu", got)
	}
}

func TestParseID_MissingID(t *testing.T) {
	if got := ParseID([]byte("NAME=Test\n")); got != "" {
		t.Errorf("got %q, want empty", got)
	}
}

func TestParseID_UnknownIDVerbatim(t *testing.T) {
	if got := ParseID([]byte("ID=fedora\n")); got != "fedora" {
		t.Errorf("got %q, want fedora", got)
	}
}

func TestParseID_CommentsAndBlanks(t *testing.T) {
	content := `# comment

NAME="Test"
# ID below
ID=arch`
	if got := ParseID([]byte(content)); got != "arch" {
		t.Errorf("got %q, want arch", got)
	}
}

func TestDetect_FallbackToLinux(t *testing.T) {
	orig := osReleasePaths
	defer func() { osReleasePaths = orig }()
	osReleasePaths = []string{filepath.Join(t.TempDir(), "nonexistent")}
	if got := Detect(); got != "linux" {
		t.Errorf("got %q, want linux (fallback)", got)
	}
}

func TestDetect_ReadsFile(t *testing.T) {
	dir := t.TempDir()
	orig := osReleasePaths
	defer func() { osReleasePaths = orig }()
	path := filepath.Join(dir, "os-release")
	osReleasePaths = []string{path}
	if err := os.WriteFile(path, []byte("ID=ubuntu\n"), 0o644); err != nil {
		t.Fatalf("write: %v", err)
	}
	if got := Detect(); got != "ubuntu" {
		t.Errorf("got %q, want ubuntu", got)
	}
}

func TestDetect_FallbackToUsrLib(t *testing.T) {
	dir := t.TempDir()
	orig := osReleasePaths
	defer func() { osReleasePaths = orig }()
	osReleasePaths = []string{
		filepath.Join(dir, "etc"),     // missing
		filepath.Join(dir, "usr-lib"), // fallback
	}
	if err := os.WriteFile(osReleasePaths[1], []byte("ID=alpine\n"), 0o644); err != nil {
		t.Fatalf("write: %v", err)
	}
	if got := Detect(); got != "alpine" {
		t.Errorf("got %q, want alpine (from fallback)", got)
	}
}
