package fs

import (
	"bytes"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/pkg/errors"
	"gotest.tools/assert"
)

const defaultFileMode = 0644

// PathOp is a function which accepts a Path and performs an operation on that
// path. When called with real filesystem objects (File or Dir) a PathOp modifies
// the filesystem at the path. When used with a Manifest object a PathOp updates
// the manifest to expect a value.
type PathOp func(path Path) error

type manifestResource interface {
	SetMode(mode os.FileMode)
	SetUID(uid uint32)
	SetGID(gid uint32)
}

type manifestFile interface {
	manifestResource
	SetContent(content io.ReadCloser)
}

type manifestDirectory interface {
	manifestResource
	AddSymlink(path, target string) error
	AddFile(path string, ops ...PathOp) error
	AddDirectory(path string, ops ...PathOp) error
}

// WithContent writes content to a file at Path
func WithContent(content string) PathOp {
	return func(path Path) error {
		if m, ok := path.(manifestFile); ok {
			m.SetContent(ioutil.NopCloser(strings.NewReader(content)))
			return nil
		}
		return ioutil.WriteFile(path.Path(), []byte(content), defaultFileMode)
	}
}

// WithBytes write bytes to a file at Path
func WithBytes(raw []byte) PathOp {
	return func(path Path) error {
		if m, ok := path.(manifestFile); ok {
			m.SetContent(ioutil.NopCloser(bytes.NewReader(raw)))
			return nil
		}
		return ioutil.WriteFile(path.Path(), raw, defaultFileMode)
	}
}

// AsUser changes ownership of the file system object at Path
func AsUser(uid, gid int) PathOp {
	return func(path Path) error {
		if m, ok := path.(manifestResource); ok {
			m.SetUID(uint32(uid))
			m.SetGID(uint32(gid))
			return nil
		}
		return os.Chown(path.Path(), uid, gid)
	}
}

// WithFile creates a file in the directory at path with content
func WithFile(filename, content string, ops ...PathOp) PathOp {
	return func(path Path) error {
		if m, ok := path.(manifestDirectory); ok {
			ops = append([]PathOp{WithContent(content), WithMode(defaultFileMode)}, ops...)
			return m.AddFile(filename, ops...)
		}

		fullpath := filepath.Join(path.Path(), filepath.FromSlash(filename))
		if err := createFile(fullpath, content); err != nil {
			return err
		}
		return applyPathOps(&File{path: fullpath}, ops)
	}
}

func createFile(fullpath string, content string) error {
	return ioutil.WriteFile(fullpath, []byte(content), defaultFileMode)
}

// WithFiles creates all the files in the directory at path with their content
func WithFiles(files map[string]string) PathOp {
	return func(path Path) error {
		if m, ok := path.(manifestDirectory); ok {
			for filename, content := range files {
				// TODO: remove duplication with WithFile
				if err := m.AddFile(filename, WithContent(content), WithMode(defaultFileMode)); err != nil {
					return err
				}
			}
			return nil
		}

		for filename, content := range files {
			fullpath := filepath.Join(path.Path(), filepath.FromSlash(filename))
			if err := createFile(fullpath, content); err != nil {
				return err
			}
		}
		return nil
	}
}

// FromDir copies the directory tree from the source path into the new Dir
func FromDir(source string) PathOp {
	return func(path Path) error {
		if _, ok := path.(manifestDirectory); ok {
			return errors.New("use manifest.FromDir")
		}
		return copyDirectory(source, path.Path())
	}
}

// WithDir creates a subdirectory in the directory at path. Additional PathOp
// can be used to modify the subdirectory
func WithDir(name string, ops ...PathOp) PathOp {
	const defaultMode = 0755
	return func(path Path) error {
		if m, ok := path.(manifestDirectory); ok {
			ops = append([]PathOp{WithMode(defaultMode)}, ops...)
			return m.AddDirectory(name, ops...)
		}

		fullpath := filepath.Join(path.Path(), filepath.FromSlash(name))
		err := os.MkdirAll(fullpath, defaultMode)
		if err != nil {
			return err
		}
		return applyPathOps(&Dir{path: fullpath}, ops)
	}
}

// Apply the PathOps to the File
func Apply(t assert.TestingT, path Path, ops ...PathOp) {
	if ht, ok := t.(helperT); ok {
		ht.Helper()
	}
	assert.NilError(t, applyPathOps(path, ops))
}

func applyPathOps(path Path, ops []PathOp) error {
	for _, op := range ops {
		if err := op(path); err != nil {
			return err
		}
	}
	return nil
}

// WithMode sets the file mode on the directory or file at path
func WithMode(mode os.FileMode) PathOp {
	return func(path Path) error {
		if m, ok := path.(manifestResource); ok {
			m.SetMode(mode)
			return nil
		}
		return os.Chmod(path.Path(), mode)
	}
}

func copyDirectory(source, dest string) error {
	entries, err := ioutil.ReadDir(source)
	if err != nil {
		return err
	}
	for _, entry := range entries {
		sourcePath := filepath.Join(source, entry.Name())
		destPath := filepath.Join(dest, entry.Name())
		switch {
		case entry.IsDir():
			if err := os.Mkdir(destPath, 0755); err != nil {
				return err
			}
			if err := copyDirectory(sourcePath, destPath); err != nil {
				return err
			}
		case entry.Mode()&os.ModeSymlink != 0:
			if err := copySymLink(sourcePath, destPath); err != nil {
				return err
			}
		default:
			if err := copyFile(sourcePath, destPath); err != nil {
				return err
			}
		}
	}
	return nil
}

func copySymLink(source, dest string) error {
	link, err := os.Readlink(source)
	if err != nil {
		return err
	}
	return os.Symlink(link, dest)
}

func copyFile(source, dest string) error {
	content, err := ioutil.ReadFile(source)
	if err != nil {
		return err
	}
	return ioutil.WriteFile(dest, content, 0644)
}

// WithSymlink creates a symlink in the directory which links to target.
// Target must be a path relative to the directory.
//
// Note: the argument order is the inverse of os.Symlink to be consistent with
// the other functions in this package.
func WithSymlink(path, target string) PathOp {
	return func(root Path) error {
		if v, ok := root.(manifestDirectory); ok {
			return v.AddSymlink(path, target)
		}
		return os.Symlink(filepath.Join(root.Path(), target), filepath.Join(root.Path(), path))
	}
}

// WithHardlink creates a link in the directory which links to target.
// Target must be a path relative to the directory.
//
// Note: the argument order is the inverse of os.Link to be consistent with
// the other functions in this package.
func WithHardlink(path, target string) PathOp {
	return func(root Path) error {
		if _, ok := root.(manifestDirectory); ok {
			return errors.New("WithHardlink not implemented for manifests")
		}
		return os.Link(filepath.Join(root.Path(), target), filepath.Join(root.Path(), path))
	}
}

// WithTimestamps sets the access and modification times of the file system object
// at path.
func WithTimestamps(atime, mtime time.Time) PathOp {
	return func(root Path) error {
		if _, ok := root.(manifestDirectory); ok {
			return errors.New("WithTimestamp not implemented for manifests")
		}
		return os.Chtimes(root.Path(), atime, mtime)
	}
}
