package local_test

import (
	"context"
	"errors"
	"io"
	"os"
	"path"
	"path/filepath"
	"strings"
	"testing"

	storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
	. "github.com/smartystreets/goconvey/convey"

	zerr "zotregistry.dev/zot/v2/errors"
	storageConstants "zotregistry.dev/zot/v2/pkg/storage/constants"
	"zotregistry.dev/zot/v2/pkg/storage/local"
)

func TestStorageDriver(t *testing.T) {
	driver := local.New(true)

	Convey("Test DirExists", t, func() {
		rootDir := t.TempDir()

		// Folder exists
		result := driver.DirExists(rootDir)
		So(result, ShouldBeTrue)

		// Folder name triggering ENAMETOOLONG
		result = driver.DirExists(path.Join(rootDir, strings.Repeat("1234567890", 1000)))
		So(result, ShouldBeFalse)

		// Folder which does not exist
		result = driver.DirExists(path.Join(rootDir, "someName"))
		So(result, ShouldBeFalse)

		// Path is actually a file
		fileName := "testFile"
		_, err := os.Create(path.Join(rootDir, fileName))
		So(err, ShouldBeNil)

		result = driver.DirExists(path.Join(rootDir, fileName))
		So(result, ShouldBeFalse)

		// Folder name triggering ENOTDIR a one of the parents is not a folder
		result = driver.DirExists(path.Join(rootDir, fileName, "someName"))
		So(result, ShouldBeFalse)

		// New folder created by driver
		repoName := "testRepo"
		err = driver.EnsureDir(path.Join(rootDir, repoName))
		So(err, ShouldBeNil)

		result = driver.DirExists(path.Join(rootDir, repoName))
		So(result, ShouldBeTrue)

		// Folder without permissions
		err = os.Chmod(path.Join(rootDir, repoName), 0o000)
		So(err, ShouldBeNil)
		defer os.Chmod(path.Join(rootDir, repoName), storageConstants.DefaultDirPerms) //nolint:errcheck

		result = driver.DirExists(path.Join(rootDir, repoName))
		So(result, ShouldBeTrue)

		// Invalid UTF-8 path should return false
		invalidUTF8Path := string([]byte{0xff, 0xfe, 0xfd}) // Invalid UTF-8 sequence
		result = driver.DirExists(invalidUTF8Path)
		So(result, ShouldBeFalse)
	})

	Convey("Test Walk", t, func() {
		Convey("Test all folders are walked and files are identified correctly", func() {
			rootDir := t.TempDir()
			err := driver.EnsureDir(path.Join(rootDir, "d1", "d11"))
			So(err, ShouldBeNil)
			err = driver.EnsureDir(path.Join(rootDir, "d1", "d12"))
			So(err, ShouldBeNil)
			err = driver.EnsureDir(path.Join(rootDir, "d2"))
			So(err, ShouldBeNil)
			_, err = os.Create(path.Join(rootDir, "d1", "d11", "f111"))
			So(err, ShouldBeNil)
			_, err = os.Create(path.Join(rootDir, "d2", "f21"))
			So(err, ShouldBeNil)

			fileList := []string{}
			folderList := []string{}

			err = driver.Walk(rootDir, func(fileInfo storagedriver.FileInfo) error {
				if fileInfo.IsDir() {
					folderList = append(folderList, fileInfo.Path())
				} else {
					fileList = append(fileList, fileInfo.Path())
				}

				return nil
			})
			So(err, ShouldBeNil)

			So(len(fileList), ShouldEqual, 2)
			So(fileList, ShouldContain, path.Join(rootDir, "d1", "d11", "f111"))
			So(fileList, ShouldContain, path.Join(rootDir, "d2", "f21"))
			So(len(folderList), ShouldEqual, 4)
			So(folderList, ShouldContain, path.Join(rootDir, "d1"))
			So(folderList, ShouldContain, path.Join(rootDir, "d1", "d11"))
			So(folderList, ShouldContain, path.Join(rootDir, "d1", "d12"))
			So(folderList, ShouldContain, path.Join(rootDir, "d2"))
		})

		Convey("Test deleting folders while walking raises doesn't raise errors", func() {
			rootDir := t.TempDir()
			err := driver.EnsureDir(path.Join(rootDir, "d1"))
			So(err, ShouldBeNil)
			err = driver.EnsureDir(path.Join(rootDir, "d2"))
			So(err, ShouldBeNil)

			// List/Sort d1 and d2, delete d2 while d1 is walked
			// While d2 is walked the PathNotFoundError should be ignored
			err = driver.Walk(rootDir, func(fileInfo storagedriver.FileInfo) error {
				return driver.Delete(path.Join(rootDir, "d2"))
			})
			So(err, ShouldBeNil)
		})
	})
}

func TestMove(t *testing.T) {
	Convey("Test Move file/directory operations", t, func() {
		driver := local.New(true)
		rootDir := t.TempDir()

		Convey("Test moving non-existent file", func() {
			err := driver.Move("/nonexistent", "/destination")
			So(err, ShouldNotBeNil)

			var pathNotFoundErr storagedriver.PathNotFoundError

			So(errors.As(err, &pathNotFoundErr), ShouldBeTrue)
		})

		Convey("Test successful file move", func() {
			srcFile := path.Join(rootDir, "source.txt")
			destFile := path.Join(rootDir, "dest.txt")

			// Create source file
			err := os.WriteFile(srcFile, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Move file
			err = driver.Move(srcFile, destFile)
			So(err, ShouldBeNil)

			// Verify move
			_, err = os.Stat(srcFile)
			So(err, ShouldNotBeNil)
			_, err = os.Stat(destFile)
			So(err, ShouldBeNil)
		})

		Convey("Test moving to non-existent directory", func() {
			srcFile := path.Join(rootDir, "source.txt")
			destFile := path.Join(rootDir, "nonexistent", "dest.txt")

			// Create source file
			err := os.WriteFile(srcFile, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Move file (should create destination directory)
			err = driver.Move(srcFile, destFile)
			So(err, ShouldBeNil)

			// Verify move
			_, err = os.Stat(srcFile)
			So(err, ShouldNotBeNil)
			_, err = os.Stat(destFile)
			So(err, ShouldBeNil)
		})

		Convey("Test Move() with os.MkdirAll error to trigger formatErr", func() {
			srcFile := path.Join(rootDir, "source.txt")
			// Use invalid path to trigger os.MkdirAll error
			destFile := string([]byte{0x00}) + "/dest.txt"

			// Create source file
			err := os.WriteFile(srcFile, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Move should return a formatted error
			err = driver.Move(srcFile, destFile)
			So(err, ShouldNotBeNil)

			// Should be a formatted error
			var storageErr storagedriver.Error

			So(errors.As(err, &storageErr), ShouldBeTrue)
			So(storageErr.DriverName, ShouldEqual, "local")
		})

		Convey("Test Move() with os.Rename error to trigger formatErr", func() {
			srcFile := path.Join(rootDir, "source.txt")
			destFile := path.Join(rootDir, "dest.txt")

			// Create source file
			err := os.WriteFile(srcFile, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Create destination file to cause rename conflict
			err = os.WriteFile(destFile, []byte("existing content"), 0o600)
			So(err, ShouldBeNil)

			// Move should return a formatted error (rename conflict)
			err = driver.Move(srcFile, destFile)
			// Note: On some systems, os.Rename might succeed by overwriting
			// So we just verify it doesn't panic and handle the result appropriately
			_ = err
		})
	})
}

func TestValidateHardLink(t *testing.T) {
	Convey("Test ValidateHardLink functionality", t, func() {
		rootDir := t.TempDir()

		Convey("Test successful hardlink validation", func() {
			err := local.ValidateHardLink(rootDir)
			So(err, ShouldBeNil)
		})

		Convey("Test hardlink validation on non-existent directory", func() {
			err := local.ValidateHardLink("/nonexistent/directory")
			// This might succeed or fail depending on system permissions
			// We're just testing that it doesn't panic
			_ = err
		})
	})
}

func TestWriteFile(t *testing.T) {
	Convey("Test WriteFile operations", t, func() {
		driver := local.New(true)
		rootDir := t.TempDir()

		Convey("Test successful file write", func() {
			content := []byte("test content")
			filePath := path.Join(rootDir, "test.txt")

			n, err := driver.WriteFile(filePath, content)
			So(err, ShouldBeNil)
			So(n, ShouldEqual, len(content))

			// Verify file was created
			_, err = os.Stat(filePath)
			So(err, ShouldBeNil)
		})

		Convey("Test write to non-existent directory", func() {
			content := []byte("test content")
			filePath := "/nonexistent/path/file.txt"

			n, err := driver.WriteFile(filePath, content)
			So(err, ShouldNotBeNil)
			So(n, ShouldEqual, -1)
		})

		Convey("Test write empty content", func() {
			content := []byte("")
			filePath := path.Join(rootDir, "empty.txt")

			n, err := driver.WriteFile(filePath, content)
			So(err, ShouldBeNil)
			So(n, ShouldEqual, 0)
		})

		Convey("Test WriteFile() with io.Copy error to trigger formatErr", func() {
			// Create a file
			filePath := path.Join(rootDir, "test.txt")
			err := os.WriteFile(filePath, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// WriteFile should succeed normally
			content := []byte("new content")
			n, err := driver.WriteFile(filePath, content)
			So(err, ShouldBeNil)
			So(n, ShouldEqual, len(content))

			// Test with invalid path to trigger formatErr path
			// This will cause Writer to fail, which WriteFile will pass through
			invalidPath := string([]byte{0x00}) // Null byte in path
			n, err = driver.WriteFile(invalidPath, content)
			So(err, ShouldNotBeNil)
			So(n, ShouldEqual, -1)

			// Should be a formatted error
			var storageErr storagedriver.Error

			So(errors.As(err, &storageErr), ShouldBeTrue)
			So(storageErr.DriverName, ShouldEqual, "local")
		})
	})
}

func TestLink(t *testing.T) {
	Convey("Test Link hardlink operations", t, func() {
		driver := local.New(true)
		rootDir := t.TempDir()

		Convey("Test successful hardlink creation", func() {
			// Create source file
			srcFile := path.Join(rootDir, "source.txt")
			err := os.WriteFile(srcFile, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Create hardlink
			destFile := path.Join(rootDir, "link.txt")
			err = driver.Link(srcFile, destFile)
			So(err, ShouldBeNil)

			// Verify link exists
			_, err = os.Stat(destFile)
			So(err, ShouldBeNil)
		})

		Convey("Test linking non-existent file", func() {
			destFile := path.Join(rootDir, "link.txt")
			err := driver.Link("/nonexistent", destFile)
			So(err, ShouldNotBeNil)
		})

		Convey("Test linking to existing destination", func() {
			// Create source file
			srcFile := path.Join(rootDir, "source.txt")
			err := os.WriteFile(srcFile, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Create existing destination file
			destFile := path.Join(rootDir, "existing.txt")
			err = os.WriteFile(destFile, []byte("existing content"), 0o600)
			So(err, ShouldBeNil)

			// Create hardlink (should remove existing file first)
			err = driver.Link(srcFile, destFile)
			So(err, ShouldBeNil)

			// Verify link exists
			_, err = os.Stat(destFile)
			So(err, ShouldBeNil)
		})

		Convey("Test Link() with os.Remove error to trigger return err", func() {
			// Link should return os.Remove error
			err := driver.Link("", string([]byte{0x00}))
			So(err, ShouldNotBeNil)
		})
	})
}

func TestDelete(t *testing.T) {
	Convey("Test Delete operations", t, func() {
		driver := local.New(true)
		rootDir := t.TempDir()

		Convey("Test deleting non-existent file", func() {
			err := driver.Delete("/nonexistent")
			So(err, ShouldNotBeNil)

			var pathNotFoundErr storagedriver.PathNotFoundError

			So(errors.As(err, &pathNotFoundErr), ShouldBeTrue)
		})

		Convey("Test successful file deletion", func() {
			filePath := path.Join(rootDir, "test.txt")
			err := os.WriteFile(filePath, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			err = driver.Delete(filePath)
			So(err, ShouldBeNil)

			// Verify deletion
			_, err = os.Stat(filePath)
			So(err, ShouldNotBeNil)
		})

		Convey("Test deleting directory", func() {
			dirPath := path.Join(rootDir, "testdir")
			err := os.Mkdir(dirPath, 0o755)
			So(err, ShouldBeNil)

			// Create file in directory
			filePath := path.Join(dirPath, "test.txt")
			err = os.WriteFile(filePath, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			err = driver.Delete(dirPath)
			So(err, ShouldBeNil)

			// Verify deletion
			_, err = os.Stat(dirPath)
			So(err, ShouldNotBeNil)
		})

		Convey("Test Delete() with invalid path to trigger formatErr", func() {
			// Use an invalid path that will cause os.Stat to fail with a non-IsNotExist error
			invalidPath := string([]byte{0x00}) // Null byte in path is invalid on most systems

			// Delete should return a formatted error (not PathNotFoundError)
			err := driver.Delete(invalidPath)
			So(err, ShouldNotBeNil)

			// Should not be a PathNotFoundError since it's not an IsNotExist error
			var pathNotFoundErr storagedriver.PathNotFoundError

			So(errors.As(err, &pathNotFoundErr), ShouldBeFalse)

			// Should be a formatted error
			var storageErr storagedriver.Error

			So(errors.As(err, &storageErr), ShouldBeTrue)
			So(storageErr.DriverName, ShouldEqual, "local")
		})
	})
}

func TestFileInfoSize(t *testing.T) {
	Convey("Test fileInfo.Size method", t, func() {
		driver := local.New(true)
		rootDir := t.TempDir()

		Convey("Test file size calculation", func() {
			filePath := path.Join(rootDir, "test.txt")
			content := []byte("test content")
			err := os.WriteFile(filePath, content, 0o600)
			So(err, ShouldBeNil)

			fileInfo, err := driver.Stat(filePath)
			So(err, ShouldBeNil)
			So(fileInfo.Size(), ShouldEqual, int64(len(content)))
		})

		Convey("Test directory size (should be 0)", func() {
			dirPath := path.Join(rootDir, "testdir")
			err := os.Mkdir(dirPath, 0o755)
			So(err, ShouldBeNil)

			dirInfo, err := driver.Stat(dirPath)
			So(err, ShouldBeNil)
			So(dirInfo.Size(), ShouldEqual, int64(0))
		})

		Convey("Test empty file size", func() {
			filePath := path.Join(rootDir, "empty.txt")
			err := os.WriteFile(filePath, []byte(""), 0o600)
			So(err, ShouldBeNil)

			fileInfo, err := driver.Stat(filePath)
			So(err, ShouldBeNil)
			So(fileInfo.Size(), ShouldEqual, int64(0))
		})

		Convey("Test Stat() with permission error", func() {
			// Create a file
			filePath := path.Join(rootDir, "permission_test.txt")
			err := os.WriteFile(filePath, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Remove read permission
			err = os.Chmod(filePath, 0o000)
			So(err, ShouldBeNil)

			defer func() {
				_ = os.Chmod(filePath, 0o600) // Restore permissions
			}()

			// Stat should return a formatted error (not PathNotFoundError)
			_, err = driver.Stat(filePath)
			// Note: On some systems, Stat() might still succeed even with 0000 permissions
			// We just verify it doesn't panic and handles the case appropriately
			_ = err
		})

		Convey("Test Stat() with invalid path to trigger formatErr", func() {
			// Use an invalid path that will cause os.Stat to fail with a non-IsNotExist error
			invalidPath := string([]byte{0x00}) // Null byte in path is invalid on most systems

			// Stat should return a formatted error (not PathNotFoundError)
			_, err := driver.Stat(invalidPath)
			So(err, ShouldNotBeNil)

			// Should not be a PathNotFoundError since it's not an IsNotExist error
			var pathNotFoundErr storagedriver.PathNotFoundError

			So(errors.As(err, &pathNotFoundErr), ShouldBeFalse)

			// Should be a formatted error
			var storageErr storagedriver.Error

			So(errors.As(err, &storageErr), ShouldBeTrue)
			So(storageErr.DriverName, ShouldEqual, "local")
		})

		Convey("Test Stat() with non-existent file", func() {
			// Stat on non-existent file should return PathNotFoundError
			_, err := driver.Stat(path.Join(rootDir, "nonexistent.txt"))
			So(err, ShouldNotBeNil)

			// Should be a PathNotFoundError
			var pathNotFoundErr storagedriver.PathNotFoundError

			So(errors.As(err, &pathNotFoundErr), ShouldBeTrue)
			So(pathNotFoundErr.Path, ShouldContainSubstring, "nonexistent.txt")
		})
	})
}

func TestReader(t *testing.T) {
	Convey("Test Reader operations", t, func() {
		driver := local.New(true)
		rootDir := t.TempDir()

		Convey("Test reading non-existent file", func() {
			_, err := driver.Reader("/nonexistent", 0)
			So(err, ShouldNotBeNil)

			var pathNotFoundErr storagedriver.PathNotFoundError

			So(errors.As(err, &pathNotFoundErr), ShouldBeTrue)
		})

		Convey("Test reading with invalid offset", func() {
			filePath := path.Join(rootDir, "test.txt")
			content := []byte("test content")
			err := os.WriteFile(filePath, content, 0o600)
			So(err, ShouldBeNil)

			_, err = driver.Reader(filePath, 1000) // Offset beyond file size
			// Note: This might not always return an error depending on the implementation
			// We just verify it doesn't panic
			_ = err
		})

		Convey("Test successful read from beginning", func() {
			filePath := path.Join(rootDir, "test.txt")
			content := []byte("test content")
			err := os.WriteFile(filePath, content, 0o600)
			So(err, ShouldBeNil)

			reader, err := driver.Reader(filePath, 0)
			So(err, ShouldBeNil)
			defer reader.Close()

			readContent, err := io.ReadAll(reader)
			So(err, ShouldBeNil)
			So(string(readContent), ShouldEqual, string(content))
		})

		Convey("Test successful read with offset", func() {
			filePath := path.Join(rootDir, "test.txt")
			content := []byte("test content")
			err := os.WriteFile(filePath, content, 0o600)
			So(err, ShouldBeNil)

			reader, err := driver.Reader(filePath, 5) // Start from offset 5
			So(err, ShouldBeNil)
			defer reader.Close()

			readContent, err := io.ReadAll(reader)
			So(err, ShouldBeNil)
			So(string(readContent), ShouldEqual, "content")
		})

		Convey("Test ReadFile() with io.ReadAll error to trigger formatErr", func() {
			// Create a file
			filePath := path.Join(rootDir, "test.txt")
			err := os.WriteFile(filePath, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// ReadFile should succeed normally
			content, err := driver.ReadFile(filePath)
			So(err, ShouldBeNil)
			So(string(content), ShouldEqual, "test content")

			// Test with non-existent file to trigger formatErr path
			// This will cause Reader to fail, which ReadFile will pass through
			_, err = driver.ReadFile("/nonexistent")
			So(err, ShouldNotBeNil)

			// Should be a PathNotFoundError (from Reader)
			var pathNotFoundErr storagedriver.PathNotFoundError

			So(errors.As(err, &pathNotFoundErr), ShouldBeTrue)
		})

		Convey("Test Reader() with file.Seek error to trigger formatErr", func() {
			// Create a file
			filePath := path.Join(rootDir, "test.txt")
			err := os.WriteFile(filePath, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Use invalid offset to trigger file.Seek error
			_, err = driver.Reader(filePath, -1) // Negative offset should cause Seek error
			So(err, ShouldNotBeNil)

			// Should be a formatted error
			var storageErr storagedriver.Error

			So(errors.As(err, &storageErr), ShouldBeTrue)
			So(storageErr.DriverName, ShouldEqual, "local")
		})
	})
}

func TestWriter(t *testing.T) {
	Convey("Test Writer operations", t, func() {
		driver := local.New(true)
		rootDir := t.TempDir()

		Convey("Test append mode with non-existent file", func() {
			filePath := path.Join(rootDir, "test.txt")
			_, err := driver.Writer(filePath, true) // append=true
			So(err, ShouldNotBeNil)

			var pathNotFoundErr storagedriver.PathNotFoundError

			So(errors.As(err, &pathNotFoundErr), ShouldBeTrue)
		})

		Convey("Test successful writer creation (non-append)", func() {
			filePath := path.Join(rootDir, "test.txt")
			writer, err := driver.Writer(filePath, false)
			So(err, ShouldBeNil)

			defer writer.Close()

			// Write some content
			_, err = writer.Write([]byte("test content"))
			So(err, ShouldBeNil)

			// Close and verify
			err = writer.Close()
			So(err, ShouldBeNil)

			// Verify file was created
			_, err = os.Stat(filePath)
			So(err, ShouldBeNil)
		})

		Convey("Test append mode with existing file", func() {
			filePath := path.Join(rootDir, "test.txt")
			initialContent := []byte("initial ")
			err := os.WriteFile(filePath, initialContent, 0o600)
			So(err, ShouldBeNil)

			writer, err := driver.Writer(filePath, true)
			So(err, ShouldBeNil)
			defer writer.Close()

			// Append content
			_, err = writer.Write([]byte("appended"))
			So(err, ShouldBeNil)

			// Close and verify
			err = writer.Close()
			So(err, ShouldBeNil)

			// Verify content was appended
			content, err := os.ReadFile(filePath)
			So(err, ShouldBeNil)
			So(string(content), ShouldEqual, "initial appended")
		})

		Convey("Test writer with non-existent parent directory", func() {
			filePath := path.Join(rootDir, "nonexistent", "test.txt")
			writer, err := driver.Writer(filePath, false)
			So(err, ShouldBeNil)

			defer writer.Close()

			// Write some content
			_, err = writer.Write([]byte("test content"))
			So(err, ShouldBeNil)

			// Close and verify
			err = writer.Close()
			So(err, ShouldBeNil)

			// Verify file was created
			_, err = os.Stat(filePath)
			So(err, ShouldBeNil)
		})
	})
}

var (
	errMockCloseFailure = errors.New("close failed")
	errMockSyncOnClose  = errors.New("sync failed on close")
	errMockSyncOnCommit = errors.New("sync failed on commit")
)

// mockFile implements FileInterface for testing sync behavior.
type mockFile struct {
	*os.File

	syncCalled bool
	syncError  error
	closeError error
}

func (mf *mockFile) Sync() error {
	mf.syncCalled = true
	if mf.syncError != nil {
		return mf.syncError
	}

	return mf.File.Sync()
}

func (mf *mockFile) Close() error {
	if mf.closeError != nil {
		return mf.closeError
	}

	return mf.File.Close()
}

func TestFileWriterClose(t *testing.T) {
	Convey("Test fileWriter.Close() error handling", t, func() {
		driver := local.New(true)
		dir := t.TempDir()
		filePath := filepath.Join(dir, "testfile")

		Convey("Test Close() with commit=true", func() {
			// Create fileWriter with commit=true using the driver
			writer, err := driver.Writer(filePath, false)
			So(err, ShouldBeNil)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Close should succeed
			err = writer.Close()
			So(err, ShouldBeNil)
		})

		Convey("Test Close() with commit=true using mock to verify Sync()", func() {
			// Create a real file first
			realFile, err := os.Create(filePath)
			So(err, ShouldBeNil)

			// Create a mock file wrapper
			mockFile := &mockFile{File: realFile}

			// Create fileWriter with commit=true using the mock
			writer := local.NewFileWriter(mockFile, 0, true)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Close should call Sync() and succeed
			err = writer.Close()
			So(err, ShouldBeNil)

			// Verify Sync() was called
			So(mockFile.syncCalled, ShouldBeTrue)
		})

		Convey("Test Close() with commit=false", func() {
			// Create a new test file
			filePath2 := filepath.Join(dir, "testfile2")
			writer, err := driver.Writer(filePath2, false)
			So(err, ShouldBeNil)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Close should succeed
			err = writer.Close()
			So(err, ShouldBeNil)
		})

		Convey("Test Close() with commit=false using mock to verify Sync() NOT called", func() {
			// Create a real file first
			realFile, err := os.Create(filePath)
			So(err, ShouldBeNil)

			// Create a mock file wrapper
			mockFile := &mockFile{File: realFile}

			// Create fileWriter with commit=false using the mock
			writer := local.NewFileWriter(mockFile, 0, false)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Close should NOT call Sync() and succeed
			err = writer.Close()
			So(err, ShouldBeNil)

			// Verify Sync() was NOT called
			So(mockFile.syncCalled, ShouldBeFalse)
		})

		Convey("Test Close() on already closed file", func() {
			// Create a test file
			filePath3 := filepath.Join(dir, "testfile3")
			writer, err := driver.Writer(filePath3, false)
			So(err, ShouldBeNil)

			// Close once
			err = writer.Close()
			So(err, ShouldBeNil)

			// Close again should return error
			err = writer.Close()
			So(err, ShouldNotBeNil)
		})

		Convey("Test Close() with file.Close() error", func() {
			// Create a real file first
			realFile, err := os.Create(filePath)
			So(err, ShouldBeNil)

			// Create a mock file wrapper with Close() error
			mockFile := &mockFile{
				File:       realFile,
				closeError: errMockCloseFailure,
			}

			// Create fileWriter using the mock
			writer := local.NewFileWriter(mockFile, 0, false)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Close should return Close() error
			err = writer.Close()
			So(err, ShouldNotBeNil)
			So(err.Error(), ShouldEqual, "close failed")
		})
	})
}

func TestFileWriterCancel(t *testing.T) {
	Convey("Test fileWriter.Cancel()", t, func() {
		driver := local.New(true)
		dir := t.TempDir()
		filePath := filepath.Join(dir, "testfile")

		Convey("Test Cancel() on open file", func() {
			// Create a test file
			writer, err := driver.Writer(filePath, false)
			So(err, ShouldBeNil)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Cancel should succeed and remove the file
			err = writer.Cancel(context.Background())
			So(err, ShouldBeNil)

			// File should be removed
			_, err = os.Stat(filePath)
			So(err, ShouldNotBeNil)
		})

		Convey("Test Cancel() on already closed file", func() {
			// Create a test file
			filePath2 := filepath.Join(dir, "testfile2")
			writer, err := driver.Writer(filePath2, false)
			So(err, ShouldBeNil)

			// Close first
			err = writer.Close()
			So(err, ShouldBeNil)

			// Cancel on closed file should return error
			err = writer.Cancel(context.Background())
			So(err, ShouldNotBeNil)
		})
	})
}

func TestFileWriterCommit(t *testing.T) {
	Convey("Test fileWriter.Commit()", t, func() {
		driver := local.New(true)
		dir := t.TempDir()
		filePath := filepath.Join(dir, "testfile")

		Convey("Test Commit() on open file", func() {
			// Create a test file
			writer, err := driver.Writer(filePath, false)
			So(err, ShouldBeNil)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Commit should succeed
			err = writer.Commit(context.Background())
			So(err, ShouldBeNil)

			// File should still exist
			_, err = os.Stat(filePath)
			So(err, ShouldBeNil)
		})

		Convey("Test Commit() with commit=true using mock to verify Sync()", func() {
			// Create a real file first
			realFile, err := os.Create(filePath)
			So(err, ShouldBeNil)

			// Create a mock file wrapper
			mockFile := &mockFile{File: realFile}

			// Create fileWriter with commit=true using the mock
			writer := local.NewFileWriter(mockFile, 0, true)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Commit should call Sync() and succeed
			err = writer.Commit(context.Background())
			So(err, ShouldBeNil)

			// Verify Sync() was called
			So(mockFile.syncCalled, ShouldBeTrue)
		})

		Convey("Test Commit() on already committed file", func() {
			// Create a test file
			filePath2 := filepath.Join(dir, "testfile2")
			writer, err := driver.Writer(filePath2, false)
			So(err, ShouldBeNil)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Commit first time
			err = writer.Commit(context.Background())
			So(err, ShouldBeNil)

			// Commit again should return error
			err = writer.Commit(context.Background())
			So(err, ShouldNotBeNil)
		})

		Convey("Test Commit() with commit=false using mock to verify Sync() NOT called", func() {
			// Create a real file first
			realFile, err := os.Create(filePath)
			So(err, ShouldBeNil)

			// Create a mock file wrapper
			mockFile := &mockFile{File: realFile}

			// Create fileWriter with commit=false using the mock
			writer := local.NewFileWriter(mockFile, 0, false)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Commit should NOT call Sync() and succeed
			err = writer.Commit(context.Background())
			So(err, ShouldBeNil)

			// Verify Sync() was NOT called
			So(mockFile.syncCalled, ShouldBeFalse)
		})

		Convey("Test Commit() on already closed file", func() {
			// Create a test file
			filePath3 := filepath.Join(dir, "testfile3")
			writer, err := driver.Writer(filePath3, false)
			So(err, ShouldBeNil)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Close first
			err = writer.Close()
			So(err, ShouldBeNil)

			// Commit on closed file should return error
			err = writer.Commit(context.Background())
			So(err, ShouldNotBeNil)
		})

		Convey("Test Commit() on already cancelled file", func() {
			// Create a test file
			filePath4 := filepath.Join(dir, "testfile4")
			writer, err := driver.Writer(filePath4, false)
			So(err, ShouldBeNil)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Cancel first
			err = writer.Cancel(context.Background())
			So(err, ShouldBeNil)

			// Commit on cancelled file should return ErrFileAlreadyCancelled
			err = writer.Commit(context.Background())
			So(err, ShouldNotBeNil)
			So(err, ShouldEqual, zerr.ErrFileAlreadyCancelled)
		})
	})
}

func TestFileWriterWrite(t *testing.T) {
	Convey("Test fileWriter.Write()", t, func() {
		dir := t.TempDir()
		filePath := filepath.Join(dir, "testfile")

		Convey("Test Write() on open file", func() {
			// Create a test file
			driver := local.New(true)
			writer, err := driver.Writer(filePath, false)
			So(err, ShouldBeNil)

			// Write should succeed
			n, err := writer.Write([]byte("test data"))
			So(err, ShouldBeNil)
			So(n, ShouldEqual, 9)

			// Size should be updated
			So(writer.Size(), ShouldEqual, 9)
		})

		Convey("Test Sync() error handling on Close()", func() {
			// Create a real file first
			realFile, err := os.Create(filePath)
			So(err, ShouldBeNil)

			// Create a mock file wrapper with Sync() error
			mockFile := &mockFile{
				File:      realFile,
				syncError: errMockSyncOnClose,
			}

			// Create fileWriter with commit=true using the mock
			writer := local.NewFileWriter(mockFile, 0, true)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Close should return Sync() error
			err = writer.Close()
			So(err, ShouldNotBeNil)
			So(err.Error(), ShouldEqual, "sync failed on close")

			// Verify Sync() was called
			So(mockFile.syncCalled, ShouldBeTrue)
		})

		Convey("Test Write() on closed file", func() {
			// Create a test file
			filePath2 := filepath.Join(dir, "testfile2")
			driver := local.New(true)
			writer, err := driver.Writer(filePath2, false)
			So(err, ShouldBeNil)

			// Close first
			err = writer.Close()
			So(err, ShouldBeNil)

			// Write on closed file should return error
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldNotBeNil)
		})

		Convey("Test Write() on committed file", func() {
			// Create a test file
			filePath3 := filepath.Join(dir, "testfile3")
			driver := local.New(true)
			writer, err := driver.Writer(filePath3, false)
			So(err, ShouldBeNil)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Commit
			err = writer.Commit(context.Background())
			So(err, ShouldBeNil)

			// Write on committed file should return error
			_, err = writer.Write([]byte("more data"))
			So(err, ShouldNotBeNil)
		})

		Convey("Test Write() on cancelled file", func() {
			// Create a test file
			filePath4 := filepath.Join(dir, "testfile4")
			driver := local.New(true)
			writer, err := driver.Writer(filePath4, false)
			So(err, ShouldBeNil)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Cancel
			err = writer.Cancel(context.Background())
			So(err, ShouldBeNil)

			// Write on cancelled file should return ErrFileAlreadyCancelled
			_, err = writer.Write([]byte("more data"))
			So(err, ShouldNotBeNil)
			So(err, ShouldEqual, zerr.ErrFileAlreadyCancelled)
		})

		Convey("Test Sync() error handling on Commit()", func() {
			// Create a real file first
			realFile, err := os.Create(filePath)
			So(err, ShouldBeNil)

			// Create a mock file wrapper with Sync() error
			mockFile := &mockFile{
				File:      realFile,
				syncError: errMockSyncOnCommit,
			}

			// Create fileWriter with commit=true using the mock
			writer := local.NewFileWriter(mockFile, 0, true)

			// Write some data
			_, err = writer.Write([]byte("test data"))
			So(err, ShouldBeNil)

			// Commit should return Sync() error
			err = writer.Commit(context.Background())
			So(err, ShouldNotBeNil)
			So(err.Error(), ShouldEqual, "sync failed on commit")

			// Verify Sync() was called
			So(mockFile.syncCalled, ShouldBeTrue)
		})
	})
}

func TestList(t *testing.T) {
	Convey("Test List operations", t, func() {
		driver := local.New(true)
		rootDir := t.TempDir()

		Convey("Test successful listing with empty directory", func() {
			keys, err := driver.List(rootDir)
			So(err, ShouldBeNil)
			So(len(keys), ShouldEqual, 0)
		})

		Convey("Test successful listing with files and directories", func() {
			// Create test directory structure
			testDir := path.Join(rootDir, "testdir")
			err := os.Mkdir(testDir, 0o755)
			So(err, ShouldBeNil)

			// Create subdirectory
			subDir := path.Join(testDir, "subdir")
			err = os.Mkdir(subDir, 0o755)
			So(err, ShouldBeNil)

			// Create files
			_, err = os.Create(path.Join(testDir, "file1.txt"))
			So(err, ShouldBeNil)
			_, err = os.Create(path.Join(testDir, "file2.txt"))
			So(err, ShouldBeNil)
			_, err = os.Create(path.Join(subDir, "file3.txt"))
			So(err, ShouldBeNil)

			// List directory content
			keys, err := driver.List(testDir)
			So(err, ShouldBeNil)
			So(len(keys), ShouldEqual, 3)

			// Verify paths are properly constructed
			expectedPaths := []string{
				path.Join(testDir, "subdir"),
				path.Join(testDir, "file1.txt"),
				path.Join(testDir, "file2.txt"),
			}

			for _, expectedPath := range expectedPaths {
				So(keys, ShouldContain, expectedPath)
			}
		})

		Convey("Test listing non-existent directory", func() {
			nonExistentDir := path.Join(rootDir, "nonexistent")
			_, err := driver.List(nonExistentDir)
			So(err, ShouldNotBeNil)

			var pathNotFoundErr storagedriver.PathNotFoundError

			So(errors.As(err, &pathNotFoundErr), ShouldBeTrue)
			So(pathNotFoundErr.Path, ShouldEqual, nonExistentDir)
		})

		Convey("Test List() with os.ReadDir error triggering formatErr", func() {
			// Use an invalid path that will cause os.ReadDir to fail with a non-IsNotExist error
			invalidPath := string([]byte{0x00}) // Null byte in path is invalid on most systems

			_, err := driver.List(invalidPath)
			So(err, ShouldNotBeNil)

			// Should not be a PathNotFoundError since it's not an IsNotExist error
			var pathNotFoundErr storagedriver.PathNotFoundError

			So(errors.As(err, &pathNotFoundErr), ShouldBeFalse)

			// Should be a formatted error
			var storageErr storagedriver.Error

			So(errors.As(err, &storageErr), ShouldBeTrue)
			So(storageErr.DriverName, ShouldEqual, "local")
		})
	})
}

func TestSameFile(t *testing.T) {
	Convey("Test SameFile operations", t, func() {
		driver := local.New(true)
		rootDir := t.TempDir()

		Convey("Test SameFile with identical paths", func() {
			filePath := path.Join(rootDir, "test.txt")
			err := os.WriteFile(filePath, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Same file should return true
			result := driver.SameFile(filePath, filePath)
			So(result, ShouldBeTrue)
		})

		Convey("Test SameFile with different files", func() {
			filePath1 := path.Join(rootDir, "test1.txt")
			filePath2 := path.Join(rootDir, "test2.txt")

			err := os.WriteFile(filePath1, []byte("test content 1"), 0o600)
			So(err, ShouldBeNil)
			err = os.WriteFile(filePath2, []byte("test content 2"), 0o600)
			So(err, ShouldBeNil)

			// Different files should return false
			result := driver.SameFile(filePath1, filePath2)
			So(result, ShouldBeFalse)
		})

		Convey("Test SameFile with hard linked files", func() {
			filePath1 := path.Join(rootDir, "test1.txt")
			filePath2 := path.Join(rootDir, "test2.txt")

			err := os.WriteFile(filePath1, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Create hardlink
			err = os.Link(filePath1, filePath2)
			So(err, ShouldBeNil)

			// Hard linked files should return true
			result := driver.SameFile(filePath1, filePath2)
			So(result, ShouldBeTrue)
		})

		Convey("Test SameFile with non-existent first file", func() {
			filePath1 := "/nonexistent1.txt"
			filePath2 := path.Join(rootDir, "test.txt")

			err := os.WriteFile(filePath2, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Non-existent first file should return false
			result := driver.SameFile(filePath1, filePath2)
			So(result, ShouldBeFalse)
		})

		Convey("Test SameFile with non-existent second file", func() {
			filePath1 := path.Join(rootDir, "test.txt")
			filePath2 := "/nonexistent2.txt"

			err := os.WriteFile(filePath1, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Non-existent second file should return false
			result := driver.SameFile(filePath1, filePath2)
			So(result, ShouldBeFalse)
		})

		Convey("Test SameFile with both non-existent files", func() {
			filePath1 := "/nonexistent1.txt"
			filePath2 := "/nonexistent2.txt"

			// Both non-existent files should return false
			result := driver.SameFile(filePath1, filePath2)
			So(result, ShouldBeFalse)
		})

		Convey("Test SameFile with invalid path", func() {
			filePath1 := string([]byte{0x00}) // Invalid path
			filePath2 := path.Join(rootDir, "test.txt")

			err := os.WriteFile(filePath2, []byte("test content"), 0o600)
			So(err, ShouldBeNil)

			// Invalid path should return false
			result := driver.SameFile(filePath1, filePath2)
			So(result, ShouldBeFalse)
		})
	})
}
