// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build windows

package os_test

import (
	"errors"
	"fmt"
	"internal/strconv"
	"internal/syscall/windows"
	"os"
	"path/filepath"
	"syscall"
	"testing"
	"unsafe"
)

// Verify that Root.Open rejects Windows reserved names.
func TestRootWindowsDeviceNames(t *testing.T) {
	r, err := os.OpenRoot(t.TempDir())
	if err != nil {
		t.Fatal(err)
	}
	defer r.Close()
	if f, err := r.Open("NUL"); err == nil {
		t.Errorf(`r.Open("NUL") succeeded; want error"`)
		f.Close()
	}
}

// Verify that Root.Open is case-insensitive.
// (The wrong options to NtOpenFile could make operations case-sensitive,
// so this is worth checking.)
func TestRootWindowsCaseInsensitivity(t *testing.T) {
	dir := t.TempDir()
	if err := os.WriteFile(filepath.Join(dir, "file"), nil, 0666); err != nil {
		t.Fatal(err)
	}
	r, err := os.OpenRoot(dir)
	if err != nil {
		t.Fatal(err)
	}
	defer r.Close()
	f, err := r.Open("FILE")
	if err != nil {
		t.Fatal(err)
	}
	f.Close()
	if err := r.Remove("FILE"); err != nil {
		t.Fatal(err)
	}
	if _, err := os.Stat(filepath.Join(dir, "file")); !errors.Is(err, os.ErrNotExist) {
		t.Fatalf("os.Stat(file) after deletion: %v, want ErrNotFound", err)
	}
}

// TestRootSymlinkRelativity tests that symlinks created using Root.Symlink have the
// same SYMLINK_FLAG_RELATIVE value as ones creates using os.Symlink.
func TestRootSymlinkRelativity(t *testing.T) {
	dir := t.TempDir()
	root, err := os.OpenRoot(dir)
	if err != nil {
		t.Fatal(err)
	}
	defer root.Close()

	for i, test := range []struct {
		name   string
		target string
	}{{
		name:   "relative",
		target: `foo`,
	}, {
		name:   "absolute",
		target: `C:\foo`,
	}, {
		name:   "current working directory-relative",
		target: `C:foo`,
	}, {
		name:   "root-relative",
		target: `\foo`,
	}, {
		name:   "question prefix",
		target: `\\?\foo`,
	}, {
		name:   "relative with dot dot",
		target: `a\..\b`, // could be cleaned (but isn't)
	}} {
		t.Run(test.name, func(t *testing.T) {
			name := fmt.Sprintf("symlink_%v", i)
			if err := os.Symlink(test.target, filepath.Join(dir, name)); err != nil {
				t.Fatal(err)
			}
			if err := root.Symlink(test.target, name+"_at"); err != nil {
				t.Fatal(err)
			}

			osRDB, err := readSymlinkReparseData(filepath.Join(dir, name))
			if err != nil {
				t.Fatal(err)
			}
			rootRDB, err := readSymlinkReparseData(filepath.Join(dir, name+"_at"))
			if err != nil {
				t.Fatal(err)
			}
			if osRDB.Flags != rootRDB.Flags {
				t.Errorf("symlink target %q: Symlink flags = %x, Root.Symlink flags = %x", test.target, osRDB.Flags, rootRDB.Flags)
			}

			// Compare the link target.
			// os.Symlink converts current working directory-relative links
			// such as c:foo into absolute links.
			osTarget, err := os.Readlink(filepath.Join(dir, name))
			if err != nil {
				t.Fatal(err)
			}
			rootTarget, err := os.Readlink(filepath.Join(dir, name+"_at"))
			if err != nil {
				t.Fatal(err)
			}
			if osTarget != rootTarget {
				t.Errorf("symlink created with target %q: Symlink target = %q, Root.Symlink target = %q", test.target, osTarget, rootTarget)
			}
		})
	}
}

func readSymlinkReparseData(name string) (*windows.SymbolicLinkReparseBuffer, error) {
	nameu16, err := syscall.UTF16FromString(name)
	if err != nil {
		return nil, err
	}
	h, err := syscall.CreateFile(&nameu16[0], syscall.GENERIC_READ, 0, nil, syscall.OPEN_EXISTING,
		syscall.FILE_FLAG_OPEN_REPARSE_POINT|syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
	if err != nil {
		return nil, err
	}
	defer syscall.CloseHandle(h)

	var rdbbuf [syscall.MAXIMUM_REPARSE_DATA_BUFFER_SIZE]byte
	var bytesReturned uint32
	err = syscall.DeviceIoControl(h, syscall.FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
	if err != nil {
		return nil, err
	}

	rdb := (*windows.REPARSE_DATA_BUFFER)(unsafe.Pointer(&rdbbuf[0]))
	if rdb.ReparseTag != syscall.IO_REPARSE_TAG_SYMLINK {
		return nil, fmt.Errorf("%q: not a symlink", name)
	}

	bufoff := unsafe.Offsetof(rdb.DUMMYUNIONNAME)
	symlinkBuf := (*windows.SymbolicLinkReparseBuffer)(unsafe.Pointer(&rdbbuf[bufoff]))

	return symlinkBuf, nil
}

// TestRootSymlinkToDirectory tests that Root.Symlink creates directory links
// when the target is a directory contained within the root.
func TestRootSymlinkToDirectory(t *testing.T) {
	dir := t.TempDir()
	root, err := os.OpenRoot(dir)
	if err != nil {
		t.Fatal(err)
	}
	defer root.Close()

	if err := os.Mkdir(filepath.Join(dir, "dir"), 0777); err != nil {
		t.Fatal(err)
	}
	if err := os.WriteFile(filepath.Join(dir, "file"), nil, 0666); err != nil {
		t.Fatal(err)
	}

	dir2 := t.TempDir()

	for i, test := range []struct {
		name    string
		target  string
		wantDir bool
	}{{
		name:    "directory outside root",
		target:  dir2,
		wantDir: false,
	}, {
		name:    "directory inside root",
		target:  "dir",
		wantDir: true,
	}, {
		name:    "file inside root",
		target:  "file",
		wantDir: false,
	}, {
		name:    "nonexistent inside root",
		target:  "nonexistent",
		wantDir: false,
	}} {
		t.Run(test.name, func(t *testing.T) {
			name := fmt.Sprintf("symlink_%v", i)
			if err := root.Symlink(test.target, name); err != nil {
				t.Fatal(err)
			}

			// Lstat strips the directory mode bit from reparse points,
			// so we need to use GetFileInformationByHandle directly to
			// determine if this is a directory link.
			nameu16, err := syscall.UTF16PtrFromString(filepath.Join(dir, name))
			if err != nil {
				t.Fatal(err)
			}
			h, err := syscall.CreateFile(nameu16, 0, 0, nil, syscall.OPEN_EXISTING,
				syscall.FILE_FLAG_OPEN_REPARSE_POINT|syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
			if err != nil {
				t.Fatal(err)
			}
			defer syscall.CloseHandle(h)
			var fi syscall.ByHandleFileInformation
			if err := syscall.GetFileInformationByHandle(h, &fi); err != nil {
				t.Fatal(err)
			}
			gotDir := fi.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0

			if got, want := gotDir, test.wantDir; got != want {
				t.Errorf("link target %q: isDir = %v, want %v", test.target, got, want)
			}
		})
	}
}

func TestRootOpenFileTruncateNamedPipe(t *testing.T) {
	t.Parallel()
	name := pipeName()
	pipe := newBytePipe(t, name, false)
	defer pipe.Close()

	root, err := os.OpenRoot(filepath.Dir(name))
	if err != nil {
		t.Fatal(err)
	}
	defer root.Close()

	f, err := root.OpenFile(filepath.Base(name), os.O_TRUNC|os.O_RDWR|os.O_CREATE, 0666)
	if err != nil {
		t.Fatal(err)
	}
	f.Close()
}

func TestRootOpenFileFlags(t *testing.T) {
	t.Parallel()

	dir := t.TempDir()
	root, err := os.OpenRoot(dir)
	if err != nil {
		t.Fatal(err)
	}
	defer root.Close()

	// The only way to retrieve some of the flags passed in CreateFile
	// is using NtQueryInformationFile, which returns the file flags
	// NT equivalent. Note that FILE_SYNCHRONOUS_IO_NONALERT is always
	// set when FILE_FLAG_OVERLAPPED is not passed.
	// The flags that can't be retrieved using NtQueryInformationFile won't
	// be tested in here, but we at least know that the logic to handle them is correct.
	tests := []struct {
		flag     uint32
		wantMode uint32
	}{
		{0, windows.FILE_SYNCHRONOUS_IO_NONALERT},
		{windows.O_FILE_FLAG_OVERLAPPED, 0},
		{windows.O_FILE_FLAG_NO_BUFFERING, windows.FILE_NO_INTERMEDIATE_BUFFERING | windows.FILE_SYNCHRONOUS_IO_NONALERT},
		{windows.O_FILE_FLAG_NO_BUFFERING | windows.O_FILE_FLAG_OVERLAPPED, windows.FILE_NO_INTERMEDIATE_BUFFERING},
		{windows.O_FILE_FLAG_SEQUENTIAL_SCAN, windows.FILE_SEQUENTIAL_ONLY | windows.FILE_SYNCHRONOUS_IO_NONALERT},
		{windows.O_FILE_FLAG_WRITE_THROUGH, windows.FILE_WRITE_THROUGH | windows.FILE_SYNCHRONOUS_IO_NONALERT},
	}
	for i, tt := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			f, err := root.OpenFile(strconv.Itoa(i)+".txt", syscall.O_RDWR|syscall.O_CREAT|int(tt.flag), 0666)
			if err != nil {
				t.Fatal(err)
			}
			defer f.Close()
			var info windows.FILE_MODE_INFORMATION
			if err := windows.NtQueryInformationFile(syscall.Handle(f.Fd()), &windows.IO_STATUS_BLOCK{},
				unsafe.Pointer(&info), uint32(unsafe.Sizeof(info)), windows.FileModeInformation); err != nil {
				t.Fatal(err)
			}
			if info.Mode != tt.wantMode {
				t.Errorf("file mode = 0x%x; want 0x%x", info.Mode, tt.wantMode)
			}
		})
	}
}

func TestRootOpenFileDeleteOnClose(t *testing.T) {
	t.Parallel()
	dir := t.TempDir()
	root, err := os.OpenRoot(dir)
	if err != nil {
		t.Fatal(err)
	}
	defer root.Close()
	const name = "test.txt"
	f, err := root.OpenFile(name, syscall.O_RDWR|syscall.O_CREAT|windows.O_FILE_FLAG_DELETE_ON_CLOSE, 0666)
	if err != nil {
		t.Fatal(err)
	}
	if err := f.Close(); err != nil {
		t.Fatal(err)
	}
	// The file should be deleted after closing.
	if _, err := os.Stat(filepath.Join(dir, name)); !errors.Is(err, os.ErrNotExist) {
		t.Errorf("expected file to be deleted, got %v", err)
	}
}

func TestRootOpenFileFlagInvalid(t *testing.T) {
	t.Parallel()
	dir := t.TempDir()
	root, err := os.OpenRoot(dir)
	if err != nil {
		t.Fatal(err)
	}
	defer root.Close()
	// invalidFileFlag is the only value in the file flag range that is not supported,
	// as it is not defined in the Windows API.
	const invalidFileFlag = 0x00400000
	f, err := root.OpenFile("test.txt", syscall.O_RDWR|syscall.O_CREAT|invalidFileFlag, 0666)
	if !errors.Is(err, os.ErrInvalid) {
		t.Fatalf("expected os.ErrInvalid, got %v", err)
	}
	f.Close()
}
