// Copyright 2025 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//  1. Redistributions of source code must retain the above copyright notice, this
//     list of conditions and the following disclaimer.
//
//  2. Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//  3. Neither the name of the copyright holder nor the names of its
//     contributors may be used to endorse or promote products derived from
//     this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Contains implementation of oswrapper interfaces using fstest.
package oswrapper

import (
	"errors"
	"fmt"
	"io"
	"io/fs"
	"os"
	"path"
	"path/filepath"
	"strings"
	"sync/atomic"
	"syscall"
	"testing/fstest"
	"time"
)

var (
	ErrPwdNotSet  = errors.New("PWD not set in test environment")
	ErrHomeNotSet = errors.New("HOME not set in test environment")
)

// --- OSWrapper implementation ---

// FSTestOSWrapper is an in-memory implementation of OSWrapper for testing.
// It uses a map to simulate a filesystem, which can be used to create
// a read-only fstest.MapFS for read operations. Write operations
// manipulate the map directly.
// Caveats/known differences from real os.* functions:
//   - Paths in error messages will never have a leading / even if it was in
//     the provided path. For example, ReadFile("/root") when /root does not
//     exist will have the error message "open root: file does not exist". This
//     is a side-effect of fs.FS requiring that Open() reject names that do not
//     satisfy fs.ValidPath(), which requires that there is no leading /.
//     TODO(crbug.com/436025865): Update the implementation to correctly add
//     leading / back in.
//   - The current working directory is not taken into account. For example,
//     creating /root/subdir/file.txt, changing to /root/subdir, and attempting
//     to open file.txt will fail. This cannot currently be easily worked
//     around at the moment since the CWD-aware logic lives in EnvironProvider
//     while filesystem operations live in FilesystemReaderWriter.
//     TODO(crbug.com/436025865): Merge everything into FSTestOSWrapper so that
//     the filesystem can be CWD-aware.
type FSTestOSWrapper struct {
	FSTestEnvironProvider
	FSTestFilesystemReaderWriter
}

// CreateFSTestOSWrapper creates a new FSTestOSWrapper with an empty in-memory filesystem.
func CreateFSTestOSWrapper() FSTestOSWrapper {
	return FSTestOSWrapper{
		FSTestEnvironProvider{env: make(map[string]string)},
		FSTestFilesystemReaderWriter{
			FS: make(map[string]*fstest.MapFile),
		},
	}
}

// CreateFSTestOSWrapperWithRealEnv creates a new FSTestOSWrapper with an empty in-memory filesystem
// and an environment initialized from the current process's environment.
func CreateFSTestOSWrapperWithRealEnv() FSTestOSWrapper {
	envMap := make(map[string]string)
	for _, e := range os.Environ() {
		pair := strings.SplitN(e, "=", 2)
		if len(pair) == 2 {
			envMap[pair[0]] = pair[1]
		}
	}

	// os.Getwd() and os.UserHomeDir() are not always from environment variables on all systems, but
	// to simplify the test wrapper PWD and HOME will be populated from them.
	if _, ok := envMap["PWD"]; !ok {
		if wd, err := os.Getwd(); err == nil {
			envMap["PWD"] = wd
		}
	}
	if _, ok := envMap["HOME"]; !ok {
		if home, err := os.UserHomeDir(); err == nil {
			envMap["HOME"] = home
		}
	}

	return FSTestOSWrapper{
		FSTestEnvironProvider: FSTestEnvironProvider{env: envMap},
		FSTestFilesystemReaderWriter: FSTestFilesystemReaderWriter{
			FS: make(map[string]*fstest.MapFile),
		},
	}
}

// --- EnvironProvider implementation ---

// FSTestEnvironProvider is a stub implementation of EnvironProvider that uses a map.
type FSTestEnvironProvider struct {
	env map[string]string
}

// EnvMap returns the internal environment map.
// This is intended for testing purposes.
func (p FSTestEnvironProvider) EnvMap() map[string]string {
	return p.env
}

// Setenv sets an environment variable in the test provider.
func (p FSTestEnvironProvider) Setenv(key, value string) {
	p.env[key] = value
}

func (p FSTestEnvironProvider) Environ() []string {
	result := make([]string, 0, len(p.env))
	for k, v := range p.env {
		result = append(result, k+"="+v)
	}
	return result
}

func (p FSTestEnvironProvider) Getenv(key string) string {
	// os.Getenv returns "" for a missing key, which is the same as a map lookup.
	return p.env[key]
}

func (p FSTestEnvironProvider) Getwd() (string, error) {
	if wd, ok := p.env["PWD"]; ok {
		return wd, nil
	}
	// The specific error returned by os.Getwd is very system dependent, so just returning a package
	// error
	return "", ErrPwdNotSet
}

func (p FSTestEnvironProvider) UserHomeDir() (string, error) {
	if home, ok := p.env["HOME"]; ok {
		return home, nil
	}
	// The specific error returned by os.UserHomeDir() is very system dependent, so just returning
	// a package error
	return "", ErrHomeNotSet
}

// --- FilesystemReaderWriter implementation ---

// FSTestFilesystemReaderWriter provides an in-memory implementation of FilesystemReaderWriter.
// It holds the map that represents the filesystem.
type FSTestFilesystemReaderWriter struct {
	FS map[string]*fstest.MapFile
}

// CleanPath converts an OS dependent path into a fs.FS compatible path that can be used as a key
// within FSTestOSWrapper
func (w FSTestFilesystemReaderWriter) CleanPath(pathStr string) string {
	// Replace all backslashes with forward slashes to handle Windows paths on any OS.
	p := strings.ReplaceAll(pathStr, "\\", "/")
	// Use the platform-agnostic path package to clean the path.
	p = path.Clean(p)

	// Normalize the path to be compatible with fs.FS
	p = strings.TrimPrefix(p, "/")
	if p == "" {
		p = "." // The canonical representation of the root in a fs.FS.
	}
	return p
}

// fs returns a read-only fs.FS view of the underlying map.
func (w FSTestFilesystemReaderWriter) fs() fs.FS {
	return legacyBehaviorFS{mapFS: fstest.MapFS(w.FS)}
}

// legacyBehaviorFS is a wrapper around fstest.MapFS that only implements fs.FS.
// This is needed in Go 1.25+ because MapFS implements io/fs.ReadLinkFS, but its resolveSymlinks
// method does not support absolute paths, instead rejecting them with an error. This causes the
// _MatchesReal tests for the fake filesystem to fail since the real filesystem does support
// absolute paths for symlinks. By hiding io/fs.ReadLinkFS, fs.WalkDir falls back to the default
// behavior of not following symlinks.
//
// Additionally, Go 1.25's MapFS.Open auto-resolves symlinks, which causes fs.WalkDir to follow root
// symlinks to directories, violating filepath.Walk behavior. To fix this, Open is overridden to
// return a custom file handle for symlinks found in the map, preventing resolution.
type legacyBehaviorFS struct {
	mapFS fstest.MapFS
}

// Open overrides MapFS.Open to prevent symlink resolution for entries in mapFS.
func (f legacyBehaviorFS) Open(name string) (fs.File, error) {
	file := f.mapFS[name]
	if file != nil && file.Mode&fs.ModeSymlink != 0 {
		return noFollowFile{name: name, file: file}, nil
	}
	return f.mapFS.Open(name)
}

// noFollowFile is a custom fs.File handle for symlinks in legacyBehaviorFS.
// It reports its own file info as a symlink and does not follow the target.
type noFollowFile struct {
	name   string
	file   *fstest.MapFile
	offset int64
}

func (f noFollowFile) Stat() (fs.FileInfo, error) {
	return &mapFileInfo{path: f.name, file: f.file}, nil
}

func (f noFollowFile) Close() error { return nil }

func (f noFollowFile) Read(b []byte) (int, error) {
	if f.offset >= int64(len(f.file.Data)) {
		return 0, io.EOF
	}
	n := copy(b, f.file.Data[f.offset:])
	f.offset += int64(n)
	return n, nil
}

// resolvePath resolves symlinks in the given path.
// It assumes pathStr is a cleaned path (as returned by CleanPath).
func (w FSTestFilesystemReaderWriter) resolvePath(pathStr string) (string, error) {
	const maxSymlinks = 255
	linksWalked := 0

	parts := strings.Split(pathStr, "/")
	resolvedPath := "."

	for i := 0; i < len(parts); i++ {
		part := parts[i]

		// CleanPath guarantees that the initial pathStr doesn't contain ".." components,
		// but symlink resolution can introduce them.
		if part == ".." {
			if resolvedPath != "." {
				resolvedPath = path.Dir(resolvedPath)
			}
			continue
		}

		currentPath := ""
		if resolvedPath == "." {
			currentPath = part
		} else {
			currentPath = resolvedPath + "/" + part
		}

		entry, exists := w.FS[currentPath]
		if exists && entry.Mode&fs.ModeSymlink != 0 {
			linksWalked++
			if linksWalked > maxSymlinks {
				return "", &os.PathError{Op: "resolve", Path: pathStr, Err: syscall.ELOOP}
			}

			target := string(entry.Data)

			// Clean the target to handle OS specific separators and redundancies.
			cleanedTarget := w.CleanPath(target)

			// Check for absolute path.
			// Note: w.CleanPath removes the leading separator, so check the raw target.
			isAbs := filepath.IsAbs(target) || strings.HasPrefix(target, "/")

			targetParts := strings.Split(cleanedTarget, "/")
			if cleanedTarget == "." {
				targetParts = []string{}
			}

			if isAbs {
				resolvedPath = "."
				remaining := parts[i+1:]
				// Create new slice to be safe
				parts = make([]string, 0, len(targetParts)+len(remaining))
				parts = append(parts, targetParts...)
				parts = append(parts, remaining...)
				i = -1
			} else {
				remaining := parts[i+1:]
				head := parts[:i]
				newParts := make([]string, 0, len(head)+len(targetParts)+len(remaining))
				newParts = append(newParts, head...)
				newParts = append(newParts, targetParts...)
				newParts = append(newParts, remaining...)
				parts = newParts
				i--
			}
			continue
		}

		resolvedPath = currentPath
	}
	return resolvedPath, nil
}

// mapFileInfo wraps a fstest.MapFile to implement the os.FileInfo interface.
// It holds a pointer to the MapFile and the file's full path to derive its base name.
type mapFileInfo struct {
	path string
	file *fstest.MapFile
}

// Name returns the base name of the file.
func (i *mapFileInfo) Name() string {
	return filepath.Base(i.path)
}

// Size returns the length of the file's data in bytes.
func (i *mapFileInfo) Size() int64 {
	return int64(len(i.file.Data))
}

// Mode returns the file mode bits.
func (i *mapFileInfo) Mode() fs.FileMode {
	return i.file.Mode
}

// ModTime returns the modification time.
func (i *mapFileInfo) ModTime() time.Time {
	return i.file.ModTime
}

// IsDir returns true if the entry is a directory.
func (i *mapFileInfo) IsDir() bool {
	return i.file.Mode.IsDir()
}

// Sys returns the underlying data source (can be nil).
func (i *mapFileInfo) Sys() any {
	return i.file.Sys
}

// fstestFileHandle implements the oswrapper.File interface for the in-memory fstest map.
type fstestFileHandle struct {
	path         string
	originalPath string
	info         os.FileInfo
	fsMap        *map[string]*fstest.MapFile
	content      []byte
	offset       int64
	flag         int
	closed       bool
}

// --- FilesystemReader implementation ---

func (w FSTestFilesystemReaderWriter) Open(name string) (File, error) {
	return w.OpenFile(name, os.O_RDONLY, 0)
}

func (w FSTestFilesystemReaderWriter) OpenFile(name string, flag int, perm os.FileMode) (File, error) {
	path := w.CleanPath(name)

	// If O_EXCL is set and the path exists (even as a symlink), fail.
	// Check the original path in the map directly.
	if _, exists := w.FS[path]; exists {
		if flag&os.O_CREATE != 0 && flag&os.O_EXCL != 0 {
			return nil, &os.PathError{Op: "open", Path: name, Err: os.ErrExist}
		}
	}

	// Resolve the path to handle symlinks.
	// If the file doesn't exist, resolvePath will return the path where it *should* be
	// (resolving parent symlinks).
	resolvedPath, err := w.resolvePath(path)
	if err != nil {
		// If resolvePath fails, it might be because of a loop or other error.
		// However, if creating a file, it might be okay if the final component doesn't exist.
		// But resolvePath returns the path including the non-existent final component if parents resolve.
		// So real errors from resolvePath (like ELOOP) should be propagated.
		return nil, &os.PathError{Op: "open", Path: name, Err: err}
	}

	// Work with the resolved path from now on.
	mapFile, exists := w.FS[resolvedPath]

	// Check if a parent component of the path is a file.
	dir := filepath.Dir(resolvedPath)
	if dir != "." && dir != "" {
		parentInfo, parentExists := w.FS[dir]
		if parentExists && !parentInfo.Mode.IsDir() {
			return nil, &os.PathError{Op: "open", Path: name, Err: fmt.Errorf("not a directory")}
		}
	}

	if flag&os.O_CREATE != 0 {
		if !exists {
			parent := filepath.Dir(resolvedPath)
			if parent != "." && parent != "" {
				parentInfo, parentExists := w.FS[parent]
				if !parentExists {
					return nil, &os.PathError{Op: "open", Path: name, Err: os.ErrNotExist}
				}
				if !parentInfo.Mode.IsDir() {
					return nil, &os.PathError{Op: "open", Path: name, Err: fmt.Errorf("not a directory")}
				}
			}
			newFile := &fstest.MapFile{Data: []byte{}, Mode: perm, ModTime: time.Now()}
			w.FS[resolvedPath] = newFile
			mapFile = newFile
			exists = true
		}
	}

	if !exists {
		return nil, &os.PathError{Op: "open", Path: name, Err: os.ErrNotExist}
	}

	if mapFile.Mode.IsDir() {
		if flag&(os.O_WRONLY|os.O_RDWR) != 0 {
			return nil, &os.PathError{Op: "open", Path: name, Err: fmt.Errorf("is a directory")}
		}
		if flag&os.O_TRUNC != 0 {
			return nil, &os.PathError{Op: "open", Path: name, Err: fmt.Errorf("is a directory")}
		}
	}

	// Create an os.FileInfo compatible wrapper for the fstest.MapFile.
	// Use the original name for the wrapper so that info.Name() matches what the user expects.
	info := &renamedFileInfo{FileInfo: &mapFileInfo{path: resolvedPath, file: mapFile}, name: filepath.Base(name)}
	handle := &fstestFileHandle{
		path:         resolvedPath,
		originalPath: name,
		info:         info,
		fsMap:        &w.FS,
		flag:         flag,
		content:      nil, // Set below
		offset:       0,   // Set below
	}

	initialData := mapFile.Data
	if flag&os.O_TRUNC != 0 {
		initialData = []byte{}
	}

	handle.content = make([]byte, len(initialData))
	copy(handle.content, initialData)

	if flag&os.O_APPEND != 0 {
		handle.offset = int64(len(handle.content))
	}

	return handle, nil
}

func (w FSTestFilesystemReaderWriter) ReadFile(name string) ([]byte, error) {
	p := w.CleanPath(name)

	resolvedPath, err := w.resolvePath(p)
	if err != nil {
		return nil, &os.PathError{Op: "read", Path: name, Err: err}
	}

	// If the path is the root, it's always a directory.
	if resolvedPath == "." {
		return nil, &os.PathError{Op: "read", Path: name, Err: fmt.Errorf("is a directory")}
	}

	// Check for an explicit entry
	if mapFile, exists := w.FS[resolvedPath]; exists {
		if mapFile.Mode.IsDir() {
			return nil, &os.PathError{Op: "read", Path: name, Err: fmt.Errorf("is a directory")}
		}
		data := make([]byte, len(mapFile.Data))
		copy(data, mapFile.Data)
		return data, nil
	}

	// No check for an implicit entry, since MkdirAll should create all the intermediate
	// directories.

	return nil, &os.PathError{Op: "open", Path: name, Err: os.ErrNotExist}
}

func (w FSTestFilesystemReaderWriter) ReadDir(dir string) ([]os.DirEntry, error) {
	p := w.CleanPath(dir)
	resolvedPath, err := w.resolvePath(p)
	if err != nil {
		return nil, &os.PathError{Op: "readdir", Path: dir, Err: err}
	}

	if mapFile, exists := w.FS[resolvedPath]; exists && !mapFile.Mode.IsDir() {
		return nil, &os.PathError{Op: "readdir", Path: dir, Err: fmt.Errorf("not a directory")}
	}
	return fs.ReadDir(w.fs(), resolvedPath)
}

// renamedFileInfo wraps an os.FileInfo to override its Name() method.
type renamedFileInfo struct {
	os.FileInfo
	name string
}

func (i *renamedFileInfo) Name() string {
	return i.name
}

func (w FSTestFilesystemReaderWriter) Stat(name string) (os.FileInfo, error) {
	p := w.CleanPath(name)
	resolved, err := w.resolvePath(p)
	if err != nil {
		return nil, err
	}
	info, err := fs.Stat(w.fs(), resolved)
	if err != nil {
		return nil, err
	}
	return &renamedFileInfo{FileInfo: info, name: filepath.Base(name)}, nil
}

func (w FSTestFilesystemReaderWriter) Walk(root string, fn filepath.WalkFunc) error {
	p := w.CleanPath(root)

	// Resolve the parent of the root to handle symlinks in the path leading to the root.
	// Do not resolve the root itself, because Walk should not follow the root if it is a symlink.
	parent := path.Dir(p)
	base := path.Base(p)

	resolvedParent, err := w.resolvePath(parent)
	if err != nil {
		return fn(root, nil, err)
	}

	// Construct the path to start walking from in the internal map.
	fsRoot := base
	if resolvedParent != "." {
		fsRoot = resolvedParent + "/" + base
	}

	walkDirFn := func(pathStr string, d fs.DirEntry, err error) error {
		// fsRoot is where the walk started in the internal FS.
		// pathStr is the current path in the internal FS.

		rel, errRel := filepath.Rel(fsRoot, pathStr)
		if errRel != nil {
			return fn(pathStr, nil, fmt.Errorf("internal error creating relative path: %w", errRel))
		}

		var fullPath string
		if rel == "." {
			fullPath = root
		} else {
			fullPath = filepath.Join(root, rel)
		}

		if err != nil {
			return fn(fullPath, nil, err)
		}
		info, errInfo := d.Info()
		if errInfo != nil {
			return fn(fullPath, nil, errInfo)
		}
		return fn(fullPath, info, nil)
	}
	return fs.WalkDir(w.fs(), fsRoot, walkDirFn)
}

// --- FilesystemWriter implementation ---

func (w FSTestFilesystemReaderWriter) Create(name string) (File, error) {
	return w.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
}

func (w FSTestFilesystemReaderWriter) Mkdir(dir string, perm os.FileMode) error {
	p := w.CleanPath(dir)

	if p == "." {
		// The root directory always exists in a fs.FS.
		// os.Mkdir returns EEXIST in this case.
		return &os.PathError{Op: "mkdir", Path: dir, Err: os.ErrExist}
	}

	if _, exists := w.FS[p]; exists {
		return &os.PathError{Op: "mkdir", Path: dir, Err: os.ErrExist}
	}

	resolvedPath, err := w.resolvePath(p)
	if err != nil {
		return &os.PathError{Op: "mkdir", Path: dir, Err: err}
	}

	if _, exists := w.FS[resolvedPath]; exists {
		return &os.PathError{Op: "mkdir", Path: dir, Err: os.ErrExist}
	}

	parent := filepath.Dir(resolvedPath)
	if parent != "." && parent != "" {
		parentInfo, parentExists := w.FS[parent]
		if !parentExists {
			return &os.PathError{Op: "mkdir", Path: dir, Err: os.ErrNotExist}
		}
		if !parentInfo.Mode.IsDir() {
			return &os.PathError{Op: "mkdir", Path: dir, Err: fmt.Errorf("not a directory")}
		}
	}
	w.FS[resolvedPath] = &fstest.MapFile{Mode: os.ModeDir | perm, ModTime: time.Now()}
	return nil
}

func (w FSTestFilesystemReaderWriter) MkdirAll(dir string, perm os.FileMode) error {
	err := w.Mkdir(dir, perm)
	if err == nil {
		return nil
	}

	if os.IsExist(err) {
		info, statErr := w.Stat(dir)
		if statErr == nil && info.IsDir() {
			// p already exists and is a directory, so return success
			return nil
		}
		// p already exists and is not a directory, so propagate the error
		return err
	}

	if !os.IsNotExist(err) && !errors.Is(err, syscall.ELOOP) {
		// Unexpected failure, probably indicating a bad path, i.e. parent is a file, so propagate the error
		return err
	}

	// At this point, it is known the problem was the parent didn't exist, so need to recursively create it.
	p := w.CleanPath(dir)
	parent := filepath.Dir(p)
	if parent == "." || parent == p {
		// The parent is the root of the filesystem, so Mkdir should have succeeded, so propagating the error.
		return err
	}

	if err := w.MkdirAll(parent, perm); err != nil {
		return err
	}

	// Creating the directory now that the parent exists.
	return w.Mkdir(p, perm)
}

// tempCounter is an incrementing value used for generating the 'random' part of  temporary file
// names.
var tempCounter atomic.Uint32

func (w FSTestFilesystemReaderWriter) MkdirTemp(dir, pattern string) (string, error) {
	prefix, suffix := pattern, ""
	if i := strings.LastIndex(pattern, "*"); i != -1 {
		prefix, suffix = pattern[:i], pattern[i+1:]
	}

	// Note: This is using deterministic values for the 'random' part of the path names. This code
	// should only be used for testing purposes, since an attacker might be able to exploit this.
	rndStr := fmt.Sprintf("%d", tempCounter.Add(1))

	name := prefix + rndStr + suffix
	path := filepath.Join(dir, name)
	err := w.Mkdir(path, 0700|os.ModeDir)
	if err != nil {
		return "", err
	}
	return path, nil
}

func (w FSTestFilesystemReaderWriter) Remove(name string) error {
	p := w.CleanPath(name)

	parent := filepath.Dir(p)
	base := filepath.Base(p)

	resolvedParent := parent
	if parent != "." {
		var err error
		resolvedParent, err = w.resolvePath(parent)
		if err != nil {
			return &os.PathError{Op: "remove", Path: name, Err: err}
		}
	}

	pathToRemove := base
	if resolvedParent != "." {
		pathToRemove = resolvedParent + "/" + base
	}

	entry, exists := w.FS[pathToRemove]
	if !exists {
		return &os.PathError{Op: "remove", Path: name, Err: os.ErrNotExist}
	}

	if entry.Mode.IsDir() {
		prefix := pathToRemove + "/"
		for k := range w.FS {
			if strings.HasPrefix(k, prefix) {
				return &os.PathError{Op: "remove", Path: name, Err: syscall.ENOTEMPTY}
			}
		}
	}
	delete(w.FS, pathToRemove)
	return nil
}

func (w FSTestFilesystemReaderWriter) RemoveAll(path string) error {
	p := w.CleanPath(path)

	parent := filepath.Dir(p)
	base := filepath.Base(p)

	resolvedParent := parent
	if parent != "." {
		var err error
		resolvedParent, err = w.resolvePath(parent)
		if err != nil {
			// If the path does not exist, RemoveAll returns nil.
			if os.IsNotExist(err) {
				return nil
			}
			return &os.PathError{Op: "removeall", Path: path, Err: err}
		}
		// If the resolved parent exists but is not a directory, this should return an error.
		// However, resolvePath resolves symlinks, so if it returns successfully,
		// the resolved path exists. Thus, a directory check is required.
		if info, exists := w.FS[resolvedParent]; exists && !info.Mode.IsDir() {
			return &os.PathError{Op: "removeall", Path: path, Err: fmt.Errorf("not a directory")}
		}
	}

	pathToRemove := base
	if resolvedParent != "." {
		pathToRemove = resolvedParent + "/" + base
	}

	entry, exists := w.FS[pathToRemove]
	if !exists {
		return nil
	}

	if entry.Mode.IsDir() {
		prefix := pathToRemove + "/"
		for key := range w.FS {
			if key == pathToRemove || strings.HasPrefix(key, prefix) {
				delete(w.FS, key)
			}
		}
	} else {
		// It's a file or symlink.
		delete(w.FS, pathToRemove)
	}
	return nil
}

func (w FSTestFilesystemReaderWriter) Symlink(oldname, newname string) error {
	p := w.CleanPath(newname)

	parent := path.Dir(p)
	base := path.Base(p)

	resolvedParent := parent
	if parent != "." && parent != "" {
		var err error
		resolvedParent, err = w.resolvePath(parent)
		if err != nil {
			return &os.PathError{Op: "symlink", Path: newname, Err: err}
		}

		parentInfo, parentExists := w.FS[resolvedParent]
		if !parentExists {
			return &os.PathError{Op: "symlink", Path: newname, Err: os.ErrNotExist}
		}
		if !parentInfo.Mode.IsDir() {
			return &os.PathError{Op: "symlink", Path: newname, Err: fmt.Errorf("not a directory")}
		}
	}

	var targetPath string
	if resolvedParent == "." {
		targetPath = base
	} else {
		targetPath = resolvedParent + "/" + base
	}

	if _, exists := w.FS[targetPath]; exists {
		return &os.PathError{Op: "symlink", Path: newname, Err: os.ErrExist}
	}

	// For symlinks, the Data field holds the target path.
	// Do NOT clean oldname (the target), as it might be a relative path intended
	// to be resolved relative to the link's location, or an absolute path.
	// Store it exactly as provided.
	w.FS[targetPath] = &fstest.MapFile{
		Data:    []byte(oldname),
		Mode:    fs.ModeSymlink | 0777,
		ModTime: time.Now(),
	}
	return nil
}

func (w FSTestFilesystemReaderWriter) WriteFile(name string, data []byte, perm os.FileMode) error {
	p := w.CleanPath(name)

	resolvedPath, err := w.resolvePath(p)
	if err != nil {
		return &os.PathError{Op: "open", Path: name, Err: err}
	}

	if info, exists := w.FS[resolvedPath]; exists {
		if info.Mode.IsDir() {
			return &os.PathError{Op: "open", Path: name, Err: fmt.Errorf("is a directory")}
		}
		// If the file exists, preserve the mode.
		perm = info.Mode
	} else {
		dir := filepath.Dir(resolvedPath)
		if dir != "." && dir != "" {
			parentInfo, parentExists := w.FS[dir]
			if !parentExists {
				return &os.PathError{Op: "open", Path: name, Err: os.ErrNotExist}
			}
			if !parentInfo.Mode.IsDir() {
				return &os.PathError{Op: "open", Path: name, Err: fmt.Errorf("not a directory")}
			}
		}
	}

	w.FS[resolvedPath] = &fstest.MapFile{Data: data, Mode: perm, ModTime: time.Now()}
	return nil
}

// --- File implementation ---

func (h *fstestFileHandle) Stat() (os.FileInfo, error) {
	if h.closed {
		return nil, &os.PathError{Op: "stat", Path: h.originalPath, Err: os.ErrClosed}
	}
	return h.info, nil
}

func (h *fstestFileHandle) Close() error {
	if h.closed {
		return &os.PathError{Op: "close", Path: h.originalPath, Err: os.ErrClosed}
	}
	h.closed = true

	// Only flush content back to the map if the file was opened for writing.
	if h.flag&(os.O_WRONLY|os.O_RDWR) != 0 {
		if mapFile, exists := (*h.fsMap)[h.path]; exists {
			mapFile.Data = h.content
			mapFile.ModTime = time.Now()
		}
	}
	return nil
}

func (h *fstestFileHandle) Read(p []byte) (int, error) {
	if h.closed {
		return 0, &os.PathError{Op: "read", Path: h.originalPath, Err: os.ErrClosed}
	}
	if h.flag&os.O_WRONLY != 0 {
		return 0, &os.PathError{Op: "read", Path: h.originalPath, Err: os.ErrInvalid}
	}

	if h.offset >= int64(len(h.content)) {
		return 0, io.EOF
	}

	n := copy(p, h.content[h.offset:])
	h.offset += int64(n)
	return n, nil
}

func (h *fstestFileHandle) Write(p []byte) (int, error) {
	if h.closed {
		return 0, &os.PathError{Op: "write", Path: h.originalPath, Err: os.ErrClosed}
	}
	if h.flag&(os.O_WRONLY|os.O_RDWR) == 0 {
		return 0, &os.PathError{Op: "write", Path: h.originalPath, Err: os.ErrInvalid}
	}

	if h.flag&os.O_APPEND != 0 {
		h.offset = int64(len(h.content))
	}

	n := len(p)
	end := h.offset + int64(n)
	if end > int64(len(h.content)) {
		newContent := make([]byte, end)
		copy(newContent, h.content)
		h.content = newContent
	}

	copy(h.content[h.offset:end], p)
	h.offset = end
	return n, nil
}

func (h *fstestFileHandle) Seek(offset int64, whence int) (int64, error) {
	if h.closed {
		return 0, &os.PathError{Op: "seek", Path: h.originalPath, Err: os.ErrClosed}
	}
	var newOffset int64
	switch whence {
	case io.SeekStart:
		newOffset = offset
	case io.SeekCurrent:
		newOffset = h.offset + offset
	case io.SeekEnd:
		newOffset = int64(len(h.content)) + offset
	default:
		return 0, &os.PathError{Op: "seek", Path: h.originalPath, Err: os.ErrInvalid}
	}

	if newOffset < 0 {
		return 0, &os.PathError{Op: "seek", Path: h.originalPath, Err: os.ErrInvalid}
	}
	h.offset = newOffset
	return h.offset, nil
}
