package mounts

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

func TestParseProc(t *testing.T) {
	// Real /proc/mounts shape, including a pseudo fs and an octal-escaped space.
	data := `proc /proc proc rw,nosuid,nodev,noexec 0 0
/dev/sda1 / ext4 rw,relatime 0 0
/dev/sdb1 /mnt/my\040disk ext4 rw 0 0
`
	got := parseProc(data)
	want := []Mount{
		{Device: "proc", Mountpoint: "/proc", FSType: "proc", Options: "rw,nosuid,nodev,noexec"},
		{Device: "/dev/sda1", Mountpoint: "/", FSType: "ext4", Options: "rw,relatime"},
		{Device: "/dev/sdb1", Mountpoint: "/mnt/my disk", FSType: "ext4", Options: "rw"},
	}
	if !reflect.DeepEqual(got, want) {
		t.Errorf("parseProc:\n got %+v\nwant %+v", got, want)
	}
}

func TestUnescape(t *testing.T) {
	tests := []struct {
		name string
		in   string
		want string
	}{
		{name: "octal space", in: `/mnt/my\040disk`, want: "/mnt/my disk"},
		{name: "no escapes", in: `/no/escapes`, want: "/no/escapes"},
		{name: "tab", in: `tab\011here`, want: "tab\there"},
		{name: "backslash", in: `back\134slash`, want: `back\slash`},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := Unescape(tt.in); got != tt.want {
				t.Errorf("Unescape(%q) = %q, want %q", tt.in, got, tt.want)
			}
		})
	}
}

func TestProc(t *testing.T) {
	dir := t.TempDir()
	f := filepath.Join(dir, "mounts")
	if err := os.WriteFile(f, []byte("/dev/sda1 / ext4 rw 0 0\n"), 0644); err != nil {
		t.Fatal(err)
	}
	old := procMounts
	procMounts = f
	defer func() { procMounts = old }()

	got, err := Proc()
	if err != nil {
		t.Fatal(err)
	}
	if len(got) != 1 || got[0].Mountpoint != "/" {
		t.Errorf("Proc() = %+v", got)
	}
}
