// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fs

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/user"
	"path/filepath"
	"sync"
	"time"
)

var OsFs FileSystem = osFs{}

func NewMockFs(files map[string][]byte) *MockFs {
	workDir := "/cwd"
	fs := &MockFs{
		Clock:   NewClock(time.Unix(2, 2)),
		workDir: workDir,
	}
	fs.root = *fs.newDir()
	fs.MkDirs(workDir)

	for path, bytes := range files {
		dir := filepath.Dir(path)
		fs.MkDirs(dir)
		fs.WriteFile(path, bytes, 0777)
	}

	return fs
}

type FileSystem interface {
	// getting information about files
	Open(name string) (file io.ReadCloser, err error)
	Lstat(path string) (stats os.FileInfo, err error)
	Stat(path string) (stats os.FileInfo, err error)
	ReadDir(path string) (contents []DirEntryInfo, err error)

	InodeNumber(info os.FileInfo) (number uint64, err error)
	DeviceNumber(info os.FileInfo) (number uint64, err error)
	PermTime(info os.FileInfo) (time time.Time, err error)

	// changing contents of the filesystem
	Rename(oldPath string, newPath string) (err error)
	WriteFile(path string, data []byte, perm os.FileMode) (err error)
	Remove(path string) (err error)
	RemoveAll(path string) (err error)

	// metadata about the filesystem
	ViewId() (id string) // Some unique id of the user accessing the filesystem
}

// DentryInfo is a subset of the functionality available through os.FileInfo that might be able
// to be gleaned through only a syscall.Getdents without requiring a syscall.Lstat of every file.
type DirEntryInfo interface {
	Name() string
	Mode() os.FileMode // the file type encoded as an os.FileMode
	IsDir() bool
}

type dirEntryInfo struct {
	name       string
	mode       os.FileMode
	modeExists bool
}

var _ DirEntryInfo = os.FileInfo(nil)

func (d *dirEntryInfo) Name() string      { return d.name }
func (d *dirEntryInfo) Mode() os.FileMode { return d.mode }
func (d *dirEntryInfo) IsDir() bool       { return d.mode.IsDir() }
func (d *dirEntryInfo) String() string    { return d.name + ": " + d.mode.String() }

// osFs implements FileSystem using the local disk.
type osFs struct{}

var _ FileSystem = (*osFs)(nil)

func (osFs) Open(name string) (io.ReadCloser, error) { return os.Open(name) }

func (osFs) Lstat(path string) (stats os.FileInfo, err error) {
	return os.Lstat(path)
}

func (osFs) Stat(path string) (stats os.FileInfo, err error) {
	return os.Stat(path)
}

func (osFs) ReadDir(path string) (contents []DirEntryInfo, err error) {
	entries, err := readdir(path)
	if err != nil {
		return nil, err
	}
	for _, entry := range entries {
		contents = append(contents, entry)
	}

	return contents, nil
}

func (osFs) Rename(oldPath string, newPath string) error {
	return os.Rename(oldPath, newPath)
}

func (osFs) WriteFile(path string, data []byte, perm os.FileMode) error {
	return ioutil.WriteFile(path, data, perm)
}

func (osFs) Remove(path string) error {
	return os.Remove(path)
}

func (osFs) RemoveAll(path string) error {
	return os.RemoveAll(path)
}

func (osFs) ViewId() (id string) {
	user, err := user.Current()
	if err != nil {
		return ""
	}
	username := user.Username

	hostname, err := os.Hostname()
	if err != nil {
		return ""
	}

	return username + "@" + hostname
}

type Clock struct {
	time time.Time
}

func NewClock(startTime time.Time) *Clock {
	return &Clock{time: startTime}

}

func (c *Clock) Tick() {
	c.time = c.time.Add(time.Microsecond)
}

func (c *Clock) Time() time.Time {
	return c.time
}

// given "/a/b/c/d", pathSplit returns ("/a/b/c", "d")
func pathSplit(path string) (dir string, leaf string) {
	dir, leaf = filepath.Split(path)
	if dir != "/" && len(dir) > 0 {
		dir = dir[:len(dir)-1]
	}
	return dir, leaf
}

// MockFs supports singlethreaded writes and multithreaded reads
type MockFs struct {
	// configuration
	viewId       string //
	deviceNumber uint64

	// implementation
	root            mockDir
	Clock           *Clock
	workDir         string
	nextInodeNumber uint64

	// history of requests, for tests to check
	StatCalls      []string
	ReadDirCalls   []string
	aggregatesLock sync.Mutex
}

var _ FileSystem = (*MockFs)(nil)

type mockInode struct {
	modTime     time.Time
	permTime    time.Time
	sys         interface{}
	inodeNumber uint64
	readErr     error
}

func (m mockInode) ModTime() time.Time {
	return m.modTime
}

func (m mockInode) Sys() interface{} {
	return m.sys
}

type mockFile struct {
	bytes []byte

	mockInode
}

type mockLink struct {
	target string

	mockInode
}

type mockDir struct {
	mockInode

	subdirs  map[string]*mockDir
	files    map[string]*mockFile
	symlinks map[string]*mockLink
}

func (m *MockFs) resolve(path string, followLastLink bool) (result string, err error) {
	if !filepath.IsAbs(path) {
		path = filepath.Join(m.workDir, path)
	}
	path = filepath.Clean(path)

	return m.followLinks(path, followLastLink, 10)
}

// note that followLinks can return a file path that doesn't exist
func (m *MockFs) followLinks(path string, followLastLink bool, count int) (canonicalPath string, err error) {
	if path == "/" {
		return path, nil
	}

	parentPath, leaf := pathSplit(path)
	if parentPath == path {
		err = fmt.Errorf("Internal error: %v yields itself as a parent", path)
		panic(err.Error())
	}

	parentPath, err = m.followLinks(parentPath, true, count)
	if err != nil {
		return "", err
	}

	parentNode, err := m.getDir(parentPath, false)
	if err != nil {
		return "", err
	}
	if parentNode.readErr != nil {
		return "", &os.PathError{
			Op:   "read",
			Path: path,
			Err:  parentNode.readErr,
		}
	}

	link, isLink := parentNode.symlinks[leaf]
	if isLink && followLastLink {
		if count <= 0 {
			// probably a loop
			return "", &os.PathError{
				Op:   "read",
				Path: path,
				Err:  fmt.Errorf("too many levels of symbolic links"),
			}
		}

		if link.readErr != nil {
			return "", &os.PathError{
				Op:   "read",
				Path: path,
				Err:  link.readErr,
			}
		}

		target := m.followLink(link, parentPath)
		return m.followLinks(target, followLastLink, count-1)
	}
	return path, nil
}

func (m *MockFs) followLink(link *mockLink, parentPath string) (result string) {
	return filepath.Clean(filepath.Join(parentPath, link.target))
}

func (m *MockFs) getFile(parentDir *mockDir, fileName string) (file *mockFile, err error) {
	file, isFile := parentDir.files[fileName]
	if !isFile {
		_, isDir := parentDir.subdirs[fileName]
		_, isLink := parentDir.symlinks[fileName]
		if isDir || isLink {
			return nil, &os.PathError{
				Op:   "open",
				Path: fileName,
				Err:  os.ErrInvalid,
			}
		}

		return nil, &os.PathError{
			Op:   "open",
			Path: fileName,
			Err:  os.ErrNotExist,
		}
	}
	if file.readErr != nil {
		return nil, &os.PathError{
			Op:   "open",
			Path: fileName,
			Err:  file.readErr,
		}
	}
	return file, nil
}

func (m *MockFs) getInode(parentDir *mockDir, name string) (inode *mockInode, err error) {
	file, isFile := parentDir.files[name]
	if isFile {
		return &file.mockInode, nil
	}
	link, isLink := parentDir.symlinks[name]
	if isLink {
		return &link.mockInode, nil
	}
	dir, isDir := parentDir.subdirs[name]
	if isDir {
		return &dir.mockInode, nil
	}
	return nil, &os.PathError{
		Op:   "stat",
		Path: name,
		Err:  os.ErrNotExist,
	}

}

func (m *MockFs) Open(path string) (io.ReadCloser, error) {
	path, err := m.resolve(path, true)
	if err != nil {
		return nil, err
	}

	if err != nil {
		return nil, err
	}

	parentPath, base := pathSplit(path)
	parentDir, err := m.getDir(parentPath, false)
	if err != nil {
		return nil, err
	}
	file, err := m.getFile(parentDir, base)
	if err != nil {
		return nil, err
	}
	return struct {
		io.Closer
		*bytes.Reader
	}{
		ioutil.NopCloser(nil),
		bytes.NewReader(file.bytes),
	}, nil

}

// a mockFileInfo is for exporting file stats in a way that satisfies the FileInfo interface
type mockFileInfo struct {
	path         string
	size         int64
	modTime      time.Time // time at which the inode's contents were modified
	permTime     time.Time // time at which the inode's permissions were modified
	mode         os.FileMode
	inodeNumber  uint64
	deviceNumber uint64
}

func (m *mockFileInfo) Name() string {
	return m.path
}

func (m *mockFileInfo) Size() int64 {
	return m.size
}

func (m *mockFileInfo) Mode() os.FileMode {
	return m.mode
}

func (m *mockFileInfo) ModTime() time.Time {
	return m.modTime
}

func (m *mockFileInfo) IsDir() bool {
	return m.mode&os.ModeDir != 0
}

func (m *mockFileInfo) Sys() interface{} {
	return nil
}

func (m *MockFs) dirToFileInfo(d *mockDir, path string) (info *mockFileInfo) {
	return &mockFileInfo{
		path:         filepath.Base(path),
		size:         1,
		modTime:      d.modTime,
		permTime:     d.permTime,
		mode:         os.ModeDir,
		inodeNumber:  d.inodeNumber,
		deviceNumber: m.deviceNumber,
	}

}

func (m *MockFs) fileToFileInfo(f *mockFile, path string) (info *mockFileInfo) {
	return &mockFileInfo{
		path:         filepath.Base(path),
		size:         1,
		modTime:      f.modTime,
		permTime:     f.permTime,
		mode:         0,
		inodeNumber:  f.inodeNumber,
		deviceNumber: m.deviceNumber,
	}
}

func (m *MockFs) linkToFileInfo(l *mockLink, path string) (info *mockFileInfo) {
	return &mockFileInfo{
		path:         filepath.Base(path),
		size:         1,
		modTime:      l.modTime,
		permTime:     l.permTime,
		mode:         os.ModeSymlink,
		inodeNumber:  l.inodeNumber,
		deviceNumber: m.deviceNumber,
	}
}

func (m *MockFs) Lstat(path string) (stats os.FileInfo, err error) {
	// update aggregates
	m.aggregatesLock.Lock()
	m.StatCalls = append(m.StatCalls, path)
	m.aggregatesLock.Unlock()

	// resolve symlinks
	path, err = m.resolve(path, false)
	if err != nil {
		return nil, err
	}

	// special case for root dir
	if path == "/" {
		return m.dirToFileInfo(&m.root, "/"), nil
	}

	// determine type and handle appropriately
	parentPath, baseName := pathSplit(path)
	dir, err := m.getDir(parentPath, false)
	if err != nil {
		return nil, err
	}
	subdir, subdirExists := dir.subdirs[baseName]
	if subdirExists {
		return m.dirToFileInfo(subdir, path), nil
	}
	file, fileExists := dir.files[baseName]
	if fileExists {
		return m.fileToFileInfo(file, path), nil
	}
	link, linkExists := dir.symlinks[baseName]
	if linkExists {
		return m.linkToFileInfo(link, path), nil
	}
	// not found
	return nil, &os.PathError{
		Op:   "stat",
		Path: path,
		Err:  os.ErrNotExist,
	}
}

func (m *MockFs) Stat(path string) (stats os.FileInfo, err error) {
	// resolve symlinks
	path, err = m.resolve(path, true)
	if err != nil {
		return nil, err
	}

	return m.Lstat(path)
}

func (m *MockFs) InodeNumber(info os.FileInfo) (number uint64, err error) {
	mockInfo, ok := info.(*mockFileInfo)
	if ok {
		return mockInfo.inodeNumber, nil
	}
	return 0, fmt.Errorf("%v is not a mockFileInfo", info)
}
func (m *MockFs) DeviceNumber(info os.FileInfo) (number uint64, err error) {
	mockInfo, ok := info.(*mockFileInfo)
	if ok {
		return mockInfo.deviceNumber, nil
	}
	return 0, fmt.Errorf("%v is not a mockFileInfo", info)
}
func (m *MockFs) PermTime(info os.FileInfo) (when time.Time, err error) {
	mockInfo, ok := info.(*mockFileInfo)
	if ok {
		return mockInfo.permTime, nil
	}
	return time.Date(0, 0, 0, 0, 0, 0, 0, nil),
		fmt.Errorf("%v is not a mockFileInfo", info)
}

func (m *MockFs) ReadDir(path string) (contents []DirEntryInfo, err error) {
	// update aggregates
	m.aggregatesLock.Lock()
	m.ReadDirCalls = append(m.ReadDirCalls, path)
	m.aggregatesLock.Unlock()

	// locate directory
	path, err = m.resolve(path, true)
	if err != nil {
		return nil, err
	}
	results := []DirEntryInfo{}
	dir, err := m.getDir(path, false)
	if err != nil {
		return nil, err
	}
	if dir.readErr != nil {
		return nil, &os.PathError{
			Op:   "read",
			Path: path,
			Err:  dir.readErr,
		}
	}
	// describe its contents
	for name, subdir := range dir.subdirs {
		dirInfo := m.dirToFileInfo(subdir, name)
		results = append(results, dirInfo)
	}
	for name, file := range dir.files {
		info := m.fileToFileInfo(file, name)
		results = append(results, info)
	}
	for name, link := range dir.symlinks {
		info := m.linkToFileInfo(link, name)
		results = append(results, info)
	}
	return results, nil
}

func (m *MockFs) Rename(sourcePath string, destPath string) error {
	// validate source parent exists
	sourcePath, err := m.resolve(sourcePath, false)
	if err != nil {
		return err
	}
	sourceParentPath := filepath.Dir(sourcePath)
	sourceParentDir, err := m.getDir(sourceParentPath, false)
	if err != nil {
		return err
	}
	if sourceParentDir == nil {
		return &os.PathError{
			Op:   "move",
			Path: sourcePath,
			Err:  os.ErrNotExist,
		}
	}
	if sourceParentDir.readErr != nil {
		return &os.PathError{
			Op:   "move",
			Path: sourcePath,
			Err:  sourceParentDir.readErr,
		}
	}

	// validate dest parent exists
	destPath, err = m.resolve(destPath, false)
	destParentPath := filepath.Dir(destPath)
	destParentDir, err := m.getDir(destParentPath, false)
	if err != nil {
		return err
	}
	if destParentDir == nil {
		return &os.PathError{
			Op:   "move",
			Path: destParentPath,
			Err:  os.ErrNotExist,
		}
	}
	if destParentDir.readErr != nil {
		return &os.PathError{
			Op:   "move",
			Path: destParentPath,
			Err:  destParentDir.readErr,
		}
	}
	// check the source and dest themselves
	sourceBase := filepath.Base(sourcePath)
	destBase := filepath.Base(destPath)

	file, sourceIsFile := sourceParentDir.files[sourceBase]
	dir, sourceIsDir := sourceParentDir.subdirs[sourceBase]
	link, sourceIsLink := sourceParentDir.symlinks[sourceBase]

	// validate that the source exists
	if !sourceIsFile && !sourceIsDir && !sourceIsLink {
		return &os.PathError{
			Op:   "move",
			Path: sourcePath,
			Err:  os.ErrNotExist,
		}

	}

	// validate the destination doesn't already exist as an incompatible type
	_, destWasFile := destParentDir.files[destBase]
	_, destWasDir := destParentDir.subdirs[destBase]
	_, destWasLink := destParentDir.symlinks[destBase]

	if destWasDir {
		return &os.PathError{
			Op:   "move",
			Path: destPath,
			Err:  errors.New("destination exists as a directory"),
		}
	}

	if sourceIsDir && (destWasFile || destWasLink) {
		return &os.PathError{
			Op:   "move",
			Path: destPath,
			Err:  errors.New("destination exists as a file"),
		}
	}

	if destWasFile {
		delete(destParentDir.files, destBase)
	}
	if destWasDir {
		delete(destParentDir.subdirs, destBase)
	}
	if destWasLink {
		delete(destParentDir.symlinks, destBase)
	}

	if sourceIsFile {
		destParentDir.files[destBase] = file
		delete(sourceParentDir.files, sourceBase)
	}
	if sourceIsDir {
		destParentDir.subdirs[destBase] = dir
		delete(sourceParentDir.subdirs, sourceBase)
	}
	if sourceIsLink {
		destParentDir.symlinks[destBase] = link
		delete(destParentDir.symlinks, sourceBase)
	}

	destParentDir.modTime = m.Clock.Time()
	sourceParentDir.modTime = m.Clock.Time()
	return nil
}

func (m *MockFs) newInodeNumber() uint64 {
	result := m.nextInodeNumber
	m.nextInodeNumber++
	return result
}

func (m *MockFs) WriteFile(filePath string, data []byte, perm os.FileMode) error {
	filePath, err := m.resolve(filePath, true)
	if err != nil {
		return err
	}
	parentPath := filepath.Dir(filePath)
	parentDir, err := m.getDir(parentPath, false)
	if err != nil || parentDir == nil {
		return &os.PathError{
			Op:   "write",
			Path: parentPath,
			Err:  os.ErrNotExist,
		}
	}
	if parentDir.readErr != nil {
		return &os.PathError{
			Op:   "write",
			Path: parentPath,
			Err:  parentDir.readErr,
		}
	}

	baseName := filepath.Base(filePath)
	_, exists := parentDir.files[baseName]
	if !exists {
		parentDir.modTime = m.Clock.Time()
		parentDir.files[baseName] = m.newFile()
	} else {
		readErr := parentDir.files[baseName].readErr
		if readErr != nil {
			return &os.PathError{
				Op:   "write",
				Path: filePath,
				Err:  readErr,
			}
		}
	}
	file := parentDir.files[baseName]
	file.bytes = data
	file.modTime = m.Clock.Time()
	return nil
}

func (m *MockFs) newFile() *mockFile {
	newFile := &mockFile{}
	newFile.inodeNumber = m.newInodeNumber()
	newFile.modTime = m.Clock.Time()
	newFile.permTime = newFile.modTime
	return newFile
}

func (m *MockFs) newDir() *mockDir {
	newDir := &mockDir{
		subdirs:  make(map[string]*mockDir, 0),
		files:    make(map[string]*mockFile, 0),
		symlinks: make(map[string]*mockLink, 0),
	}
	newDir.inodeNumber = m.newInodeNumber()
	newDir.modTime = m.Clock.Time()
	newDir.permTime = newDir.modTime
	return newDir
}

func (m *MockFs) newLink(target string) *mockLink {
	newLink := &mockLink{
		target: target,
	}
	newLink.inodeNumber = m.newInodeNumber()
	newLink.modTime = m.Clock.Time()
	newLink.permTime = newLink.modTime

	return newLink
}
func (m *MockFs) MkDirs(path string) error {
	_, err := m.getDir(path, true)
	return err
}

// getDir doesn't support symlinks
func (m *MockFs) getDir(path string, createIfMissing bool) (dir *mockDir, err error) {
	cleanedPath := filepath.Clean(path)
	if cleanedPath == "/" {
		return &m.root, nil
	}

	parentPath, leaf := pathSplit(cleanedPath)
	if len(parentPath) >= len(path) {
		return &m.root, nil
	}
	parent, err := m.getDir(parentPath, createIfMissing)
	if err != nil {
		return nil, err
	}
	if parent.readErr != nil {
		return nil, &os.PathError{
			Op:   "stat",
			Path: path,
			Err:  parent.readErr,
		}
	}
	childDir, dirExists := parent.subdirs[leaf]
	if !dirExists {
		if createIfMissing {
			// confirm that a file with the same name doesn't already exist
			_, fileExists := parent.files[leaf]
			if fileExists {
				return nil, &os.PathError{
					Op:   "mkdir",
					Path: path,
					Err:  os.ErrExist,
				}
			}
			// create this directory
			childDir = m.newDir()
			parent.subdirs[leaf] = childDir
			parent.modTime = m.Clock.Time()
		} else {
			return nil, &os.PathError{
				Op:   "stat",
				Path: path,
				Err:  os.ErrNotExist,
			}
		}
	}
	return childDir, nil

}

func (m *MockFs) Remove(path string) (err error) {
	path, err = m.resolve(path, false)
	parentPath, leaf := pathSplit(path)
	if len(leaf) == 0 {
		return fmt.Errorf("Cannot remove %v\n", path)
	}
	parentDir, err := m.getDir(parentPath, false)
	if err != nil {
		return err
	}
	if parentDir == nil {
		return &os.PathError{
			Op:   "remove",
			Path: path,
			Err:  os.ErrNotExist,
		}
	}
	if parentDir.readErr != nil {
		return &os.PathError{
			Op:   "remove",
			Path: path,
			Err:  parentDir.readErr,
		}
	}
	_, isDir := parentDir.subdirs[leaf]
	if isDir {
		return &os.PathError{
			Op:   "remove",
			Path: path,
			Err:  os.ErrInvalid,
		}
	}
	_, isLink := parentDir.symlinks[leaf]
	if isLink {
		delete(parentDir.symlinks, leaf)
	} else {
		_, isFile := parentDir.files[leaf]
		if !isFile {
			return &os.PathError{
				Op:   "remove",
				Path: path,
				Err:  os.ErrNotExist,
			}
		}
		delete(parentDir.files, leaf)
	}
	parentDir.modTime = m.Clock.Time()
	return nil
}

func (m *MockFs) Symlink(oldPath string, newPath string) (err error) {
	newPath, err = m.resolve(newPath, false)
	if err != nil {
		return err
	}

	newParentPath, leaf := pathSplit(newPath)
	newParentDir, err := m.getDir(newParentPath, false)
	if newParentDir.readErr != nil {
		return &os.PathError{
			Op:   "link",
			Path: newPath,
			Err:  newParentDir.readErr,
		}
	}
	if err != nil {
		return err
	}
	newParentDir.symlinks[leaf] = m.newLink(oldPath)
	return nil
}

func (m *MockFs) RemoveAll(path string) (err error) {
	path, err = m.resolve(path, false)
	if err != nil {
		return err
	}
	parentPath, leaf := pathSplit(path)
	if len(leaf) == 0 {
		return fmt.Errorf("Cannot remove %v\n", path)
	}
	parentDir, err := m.getDir(parentPath, false)
	if err != nil {
		return err
	}
	if parentDir == nil {
		return &os.PathError{
			Op:   "removeAll",
			Path: path,
			Err:  os.ErrNotExist,
		}
	}
	if parentDir.readErr != nil {
		return &os.PathError{
			Op:   "removeAll",
			Path: path,
			Err:  parentDir.readErr,
		}

	}
	_, isFile := parentDir.files[leaf]
	_, isLink := parentDir.symlinks[leaf]
	if isFile || isLink {
		return m.Remove(path)
	}
	_, isDir := parentDir.subdirs[leaf]
	if !isDir {
		if !isDir {
			return &os.PathError{
				Op:   "removeAll",
				Path: path,
				Err:  os.ErrNotExist,
			}
		}
	}

	delete(parentDir.subdirs, leaf)
	parentDir.modTime = m.Clock.Time()
	return nil
}

func (m *MockFs) SetReadable(path string, readable bool) error {
	var readErr error
	if !readable {
		readErr = os.ErrPermission
	}
	return m.SetReadErr(path, readErr)
}

func (m *MockFs) SetReadErr(path string, readErr error) error {
	path, err := m.resolve(path, false)
	if err != nil {
		return err
	}
	parentPath, leaf := filepath.Split(path)
	parentDir, err := m.getDir(parentPath, false)
	if err != nil {
		return err
	}
	if parentDir.readErr != nil {
		return &os.PathError{
			Op:   "chmod",
			Path: parentPath,
			Err:  parentDir.readErr,
		}
	}

	inode, err := m.getInode(parentDir, leaf)
	if err != nil {
		return err
	}
	inode.readErr = readErr
	inode.permTime = m.Clock.Time()
	return nil
}

func (m *MockFs) ClearMetrics() {
	m.ReadDirCalls = []string{}
	m.StatCalls = []string{}
}

func (m *MockFs) ViewId() (id string) {
	return m.viewId
}

func (m *MockFs) SetViewId(id string) {
	m.viewId = id
}
func (m *MockFs) SetDeviceNumber(deviceNumber uint64) {
	m.deviceNumber = deviceNumber
}
