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

// Package fs defines the interface for all filesystems.
package fs

import (
	"errors"
	"os"
	"time"
)

var (
	// ErrInvalidArgs indicates the arguments were invalid
	ErrInvalidArgs = os.ErrInvalid

	// ErrNotFound indicates that the requested resource was not found
	ErrNotFound = os.ErrNotExist

	// ErrAlreadyExists indicates that requested resource already exists
	ErrAlreadyExists = os.ErrExist

	// ErrPermission indicates that the operation failed due to insufficient permissions
	ErrPermission = os.ErrPermission

	// ErrReadOnly indicates that the operation failed because the underlying resource is read only
	ErrReadOnly = ErrPermission

	// ErrNoSpace indicates that a resource (such as disk space) has been used up
	ErrNoSpace = errors.New("a filesystem resource has been exhausted")

	// ErrFailedPrecondition indicates the system is not in a state where the operation can succeed
	ErrFailedPrecondition = errors.New("the filesystem is not in a state required for the operation")

	// ErrNotEmpty indicates that the caller attempted to remove a non-empty directory
	ErrNotEmpty = errors.New("directory is not empty")

	// ErrNotOpen indicates that the caller is attempting to access a file or directory
	// that is not currently open.
	ErrNotOpen = errors.New("file or directory not open")

	// ErrNotAFile indicatess that the caller attempted to open a file using a path
	// that did not point to a file
	ErrNotAFile = errors.New("not a file")

	// ErrNotADir indicates that the caller attempted to open a directory using a path
	// that did not point to a directory
	ErrNotADir = errors.New("not a directory")

	// ErrIsActive indicates that the caller attempted to unlink a directory with active
	// references
	ErrIsActive = errors.New("directory has active references")

	// ErrUnmounted indicates that the entire filesystem has been unmounted, and all future
	// operations will fail
	ErrUnmounted = errors.New("operation failed because filesystem is unmounted")

	// ErrEOF indicates that an operation ended because the end the file / directory was reached
	ErrEOF = errors.New("EOF hit before operation completed")

	// ErrNotSupported indicates that the requested operation is not supported
	ErrNotSupported = errors.New("operation not supported")

	// ErrIO indicates that an otherwise unspecified error occured during an I/O operation.
	ErrIO = errors.New("error occured during I/O")
)

// FileType describes the type of a given file.
type FileType int

// Generic FileTypes.
const (
	FileTypeUnknown FileType = iota
	FileTypeRegularFile
	FileTypeDirectory
	FileTypeCharacterDevice
	FileTypeBlockDevice
	FileTypeFifo
	FileTypeSocket
	FileTypeSymlink
)

// OpenFlags defines the options a client can request when opening a file or directory.
type OpenFlags uint32

const (
	// OpenFlagRead indicates the file should be opened with read permissions
	OpenFlagRead OpenFlags = 1 << iota
	// OpenFlagWrite indicates the file should be opened with write permissions
	OpenFlagWrite
	// OpenFlagAdmin indicates the connection can mount/unmount the filesystem
	OpenFlagAdmin
	// OpenFlagExecute indicates that the file should be opened executably mapable.
	OpenFlagExecute
	// OpenFlagCreate indicates the file should be created if it does not exist (only valid with
	// "write")
	OpenFlagCreate OpenFlags = 1 << (iota + 12)
	// OpenFlagExclusive indicates that the operation should fail if it already exists (only valid
	// with "create")
	OpenFlagExclusive
	// OpenFlagTruncate indicates the file should be truncated before writing (only valid with
	// "write")
	OpenFlagTruncate
	// OpenFlagDirectory indicates the operation must act on a directory
	OpenFlagDirectory
	// OpenFlagAppend indicates all writes should append to the file (only valid with "write")
	OpenFlagAppend
	_ // NoRemote
	// OpenFlagPath indicates the operation should only open the file descriptor,
	// not actually opening the file.
	OpenFlagPath
	// OpenFlagFile indicates the operation must act on a file
	OpenFlagFile
	// OpenFlagDescribe indicates the open request should return a response
	OpenFlagDescribe OpenFlags = (1 << 23)
)

// Read returns if the Read permission is active
func (f OpenFlags) Read() bool {
	return f&OpenFlagRead != 0
}

// Write returns if the Write permission is active
func (f OpenFlags) Write() bool {
	return f&OpenFlagWrite != 0
}

// Admin returns if the Admin permission is active
func (f OpenFlags) Admin() bool {
	return f&OpenFlagAdmin != 0
}

// Execute returns if the Execute permission is active
func (f OpenFlags) Execute() bool {
	return f&OpenFlagExecute != 0
}

// Append returns if the Append permission is active
func (f OpenFlags) Append() bool {
	return f&OpenFlagAppend != 0
}

// Truncate returns if the Truncate flag is active
func (f OpenFlags) Truncate() bool {
	return f&OpenFlagTruncate != 0
}

// Create returns if the Create flag is active
func (f OpenFlags) Create() bool {
	return f&OpenFlagCreate != 0
}

// Exclusive returns if the Exclusive flag is active
func (f OpenFlags) Exclusive() bool {
	return f&OpenFlagExclusive != 0
}

// File returns if the File flag is active
func (f OpenFlags) File() bool {
	return f&OpenFlagFile != 0
}

// Directory returns if the Directory flag is active
func (f OpenFlags) Directory() bool {
	return f&OpenFlagDirectory != 0
}

func (f OpenFlags) Path() bool {
	return f&OpenFlagPath != 0
}

func (f OpenFlags) Describe() bool {
	return f&OpenFlagDescribe != 0
}

// Whence is used to explain the meaning of an offset in a file
const (
	// WhenceFromStart means the offset starts at the beginning of the file
	WhenceFromStart = iota
	// WhenceFromCurrent means the offset starts at the current file position
	WhenceFromCurrent
	// WhenceFromEnd means the offset starts at the end of the file
	WhenceFromEnd
)

// FileSystemOptions defines the options a client can request for a filesystem.
type FileSystemOptions int

const (
	// ReadOnly indicates that the file system should be opened only for reading.
	ReadOnly FileSystemOptions = 1 << iota

	// ReadWrite indicates that the file system should be opened for reading as well as
	// writing.
	ReadWrite

	// Force indicates that the file system should be opened regardless of the feature
	// sets listed in the superblock.
	Force
)

// Dirent represents a directory entry in a generic file system.
type Dirent interface {
	// GetType returns the generic FileType of a Dirent.
	GetType() FileType
	// GetIno return the inode associated with the dirent,
	// if there is one.
	GetIno() uint64
	// GetName returns the name of a Dirent.
	GetName() string
}

// FileSystem represents a generic filesystem.
type FileSystem interface {
	// Blockcount return the total number of blocks in the file system.
	Blockcount() int64

	// Blocksize returns the size of a single block (in bytes) in the file system.
	Blocksize() int64

	// Size returns the full size of the file system.  Equivalent to f.Blocksize() * f.Blockcount().
	Size() int64

	// Close closes the file system and cleans up any memory used by it.  To prevent memory leaks, it is
	// required for callers to call Close before converting the filesystem object into garbage for the
	// GC.  The returned error is informational only and the Close may not be retried.
	Close() error

	// RootDirectory returns the root directory for the file system.  Callers must close the returned
	// directory to ensure that all changes persist to disk.
	RootDirectory() Directory

	// Type returns the type of the file system as a string
	Type() string

	// FreeSize returns the free capacity of the filesystem (in bytes). If the free capacity is
	// unknown, it will instead return the value of Size().
	FreeSize() int64
}

// Directory represents the generic methods that can be taken on directory.
type Directory interface {
	// Close closes the file, decrements the active reference count for it, and frees the
	// blocks pointed to by the file if there are no more active references to it and it is no
	// longer linked to by any directory.  Returns an error, if any.  The returned error is purely
	// informational and the close must not be retried.
	Close() error

	// Stat returns the size, last access time, and last modified time (if known) of the directory.
	Stat() (int64, time.Time, time.Time, error)

	// Touch updates the directory's access and modification times.
	Touch(lastAccess, lastModified time.Time) error

	// Dup returns a directory which shares all the information as 'this' directory, including the
	// permissions and file seek position.
	Dup() (Directory, error)

	// Read returns the contents of the directory and an error, if any.
	Read() ([]Dirent, error)

	// Open opens the file pointed to by "name".
	// d is considered the current directory for the "name".
	Open(name string, flags OpenFlags) (File, Directory, *Remote, error)

	// Rename renames the resource pointed to by src to dst.
	// Renaming a file or directory will not affect any active references to that file/directory.
	// Rename will overwrite dst if it already exists.  Returns an error, if any.
	Rename(dstparent Directory, src, dst string) error

	// Sync does not return until all changes to this directory have been persisted to stable
	// storage.  Returns an error, if any.
	Sync() error

	// Unlink unlinks target from its parent directory.
	// If target points to a directory, then the directory must be empty and it must not have
	// any active references.  If there are no more directories that link to target, then the blocks
	// held by target will be freed.  However, if target is a file and there are currently active
	// references to it then the blocks will not be freed until all the active references have been
	// closed. Returns an error, if any.
	Unlink(target string) error
}

// File represents a normal file on the filesystem.
type File interface {
	// Close closes the file, decrements the active reference count for it, and frees the blocks
	// pointed to by the file if there are no more active references to it and it is no longer
	// linked to by any directory.  Returns an error, if any.  The returned error is purely
	// informational and the close must not be retried.
	Close() error

	// Stat returns the size, last access time, and last modified time of the file.
	Stat() (int64, time.Time, time.Time, error)

	// Touch updates the file's access and modification times.
	Touch(lastAccess, lastModified time.Time) error

	// Dup returns a file which shares all the information as 'this' file, including the
	// permissions and file seek position.
	Dup() (File, error)

	// GetOpenFlags returns the open flags used to open the file
	GetOpenFlags() OpenFlags

	// SetOpenFlags attempts to update the open flags. May return an
	// error if the operation is not supported.
	SetOpenFlags(flags OpenFlags) error

	// Read reads a maximum of len(p) bytes into "p" from the file at a location decided by "off"
	// and "whence".
	// The seek position is only updated if fs.WhenceFromCurrent is passed as whence.
	Read(p []byte, off int64, whence int) (int, error)

	// Write writes a maximum of len(p) bytes from "p" into the file at a location decided by
	// "off" and "whence".
	// The seek position is only updated if fs.WhenceFromCurrent is passed as whence.
	Write(p []byte, off int64, whence int) (int, error)

	// Truncate reduces/expands the file to the size specified by "size" in bytes.
	// If the file length is increased, it is filled with zeroes.
	// Truncate does not modify the seek position.
	Truncate(size uint64) error

	// Tell identifies what the current seek position is.
	Tell() (int64, error)

	// Seek modified the seek position to offset + some starting position, dependent on whence.
	// Seek returns the new seek position.
	Seek(offset int64, whence int) (int64, error)

	// Sync does not return until all changes to this file have been persisted to stable storage.
	// Returns an error, if any.
	Sync() error
}
