// Copyright 2016 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 pathtools

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"syscall"
	"time"
)

// Based on Andrew Gerrand's "10 things you (probably) dont' know about Go"

type ShouldFollowSymlinks bool

const (
	FollowSymlinks     = ShouldFollowSymlinks(true)
	DontFollowSymlinks = ShouldFollowSymlinks(false)
)

var OsFs FileSystem = &osFs{}

func MockFs(files map[string][]byte) FileSystem {
	fs := &mockFs{
		files:    make(map[string][]byte, len(files)),
		dirs:     make(map[string]bool),
		symlinks: make(map[string]string),
		all:      []string(nil),
	}

	for f, b := range files {
		if tokens := strings.SplitN(f, "->", 2); len(tokens) == 2 {
			fs.symlinks[strings.TrimSpace(tokens[0])] = strings.TrimSpace(tokens[1])
			continue
		}

		fs.files[filepath.Clean(f)] = b
		dir := filepath.Dir(f)
		for dir != "." && dir != "/" {
			fs.dirs[dir] = true
			dir = filepath.Dir(dir)
		}
		fs.dirs[dir] = true
	}

	fs.dirs["."] = true
	fs.dirs["/"] = true

	for f := range fs.files {
		fs.all = append(fs.all, f)
	}

	for d := range fs.dirs {
		fs.all = append(fs.all, d)
	}

	for s := range fs.symlinks {
		fs.all = append(fs.all, s)
	}

	sort.Strings(fs.all)

	return fs
}

type ReaderAtSeekerCloser interface {
	io.Reader
	io.ReaderAt
	io.Seeker
	io.Closer
}

type FileSystem interface {
	// Open opens a file for reading.  Follows symlinks.
	Open(name string) (ReaderAtSeekerCloser, error)

	// Exists returns whether the file exists and whether it is a directory.  Follows symlinks.
	Exists(name string) (bool, bool, error)

	Glob(pattern string, excludes []string, follow ShouldFollowSymlinks) (matches, dirs []string, err error)
	glob(pattern string) (matches []string, err error)

	// IsDir returns true if the path points to a directory, false it it points to a file.  Follows symlinks.
	// Returns os.ErrNotExist if the path does not exist or is a symlink to a path that does not exist.
	IsDir(name string) (bool, error)

	// IsSymlink returns true if the path points to a symlink, even if that symlink points to a path that does
	// not exist.  Returns os.ErrNotExist if the path does not exist.
	IsSymlink(name string) (bool, error)

	// Lstat returns info on a file without following symlinks.
	Lstat(name string) (os.FileInfo, error)

	// Lstat returns info on a file.
	Stat(name string) (os.FileInfo, error)

	// ListDirsRecursive returns a list of all the directories in a path, following symlinks if requested.
	ListDirsRecursive(name string, follow ShouldFollowSymlinks) (dirs []string, err error)

	// ReadDirNames returns a list of everything in a directory.
	ReadDirNames(name string) ([]string, error)

	// Readlink returns the destination of the named symbolic link.
	Readlink(name string) (string, error)
}

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

func NewOsFs(path string) FileSystem {
	return &osFs{srcDir: path}
}

func (fs *osFs) toAbs(path string) string {
	if filepath.IsAbs(path) {
		return path
	}
	return filepath.Join(fs.srcDir, path)
}

func (fs *osFs) removeSrcDirPrefix(path string) string {
	if fs.srcDir == "" {
		return path
	}
	rel, err := filepath.Rel(fs.srcDir, path)
	if err != nil {
		panic(fmt.Errorf("unexpected failure in removeSrcDirPrefix filepath.Rel(%s, %s): %s",
			fs.srcDir, path, err))
	}
	if strings.HasPrefix(rel, "../") {
		panic(fmt.Errorf("unexpected relative path outside directory in removeSrcDirPrefix filepath.Rel(%s, %s): %s",
			fs.srcDir, path, rel))
	}
	return rel
}

func (fs *osFs) removeSrcDirPrefixes(paths []string) []string {
	if fs.srcDir != "" {
		for i, path := range paths {
			paths[i] = fs.removeSrcDirPrefix(path)
		}
	}
	return paths
}

func (fs *osFs) Open(name string) (ReaderAtSeekerCloser, error) {
	return os.Open(fs.toAbs(name))
}

func (fs *osFs) Exists(name string) (bool, bool, error) {
	stat, err := os.Stat(fs.toAbs(name))
	if err == nil {
		return true, stat.IsDir(), nil
	} else if os.IsNotExist(err) {
		return false, false, nil
	} else {
		return false, false, err
	}
}

func (fs *osFs) IsDir(name string) (bool, error) {
	info, err := os.Stat(fs.toAbs(name))
	if err != nil {
		return false, err
	}
	return info.IsDir(), nil
}

func (fs *osFs) IsSymlink(name string) (bool, error) {
	if info, err := os.Lstat(fs.toAbs(name)); err != nil {
		return false, err
	} else {
		return info.Mode()&os.ModeSymlink != 0, nil
	}
}

func (fs *osFs) Glob(pattern string, excludes []string, follow ShouldFollowSymlinks) (matches, dirs []string, err error) {
	return startGlob(fs, pattern, excludes, follow)
}

func (fs *osFs) glob(pattern string) ([]string, error) {
	paths, err := filepath.Glob(fs.toAbs(pattern))
	fs.removeSrcDirPrefixes(paths)
	return paths, err
}

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

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

// Returns a list of all directories under dir
func (fs *osFs) ListDirsRecursive(name string, follow ShouldFollowSymlinks) (dirs []string, err error) {
	return listDirsRecursive(fs, name, follow)
}

func (fs *osFs) ReadDirNames(name string) ([]string, error) {
	dir, err := os.Open(fs.toAbs(name))
	if err != nil {
		return nil, err
	}
	defer dir.Close()

	contents, err := dir.Readdirnames(-1)
	if err != nil {
		return nil, err
	}

	sort.Strings(contents)
	return contents, nil
}

func (fs *osFs) Readlink(name string) (string, error) {
	return os.Readlink(fs.toAbs(name))
}

type mockFs struct {
	files    map[string][]byte
	dirs     map[string]bool
	symlinks map[string]string
	all      []string
}

func (m *mockFs) followSymlinks(name string) string {
	dir, file := saneSplit(name)
	if dir != "." && dir != "/" {
		dir = m.followSymlinks(dir)
	}
	name = filepath.Join(dir, file)

	for i := 0; i < 255; i++ {
		i++
		if i > 255 {
			panic("symlink loop")
		}
		to, exists := m.symlinks[name]
		if !exists {
			break
		}
		if filepath.IsAbs(to) {
			name = to
		} else {
			name = filepath.Join(dir, to)
		}
	}
	return name
}

func (m *mockFs) Open(name string) (ReaderAtSeekerCloser, error) {
	name = filepath.Clean(name)
	name = m.followSymlinks(name)
	if f, ok := m.files[name]; ok {
		return struct {
			io.Closer
			*bytes.Reader
		}{
			ioutil.NopCloser(nil),
			bytes.NewReader(f),
		}, nil
	}

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

func (m *mockFs) Exists(name string) (bool, bool, error) {
	name = filepath.Clean(name)
	name = m.followSymlinks(name)
	if _, ok := m.files[name]; ok {
		return ok, false, nil
	}
	if _, ok := m.dirs[name]; ok {
		return ok, true, nil
	}
	return false, false, nil
}

func (m *mockFs) IsDir(name string) (bool, error) {
	dir := filepath.Dir(name)
	if dir != "." && dir != "/" {
		isDir, err := m.IsDir(dir)

		if serr, ok := err.(*os.SyscallError); ok && serr.Err == syscall.ENOTDIR {
			isDir = false
		} else if err != nil {
			return false, err
		}

		if !isDir {
			return false, os.NewSyscallError("stat "+name, syscall.ENOTDIR)
		}
	}

	name = filepath.Clean(name)
	name = m.followSymlinks(name)

	if _, ok := m.dirs[name]; ok {
		return true, nil
	}
	if _, ok := m.files[name]; ok {
		return false, nil
	}
	return false, os.ErrNotExist
}

func (m *mockFs) IsSymlink(name string) (bool, error) {
	dir, file := saneSplit(name)
	dir = m.followSymlinks(dir)
	name = filepath.Join(dir, file)

	if _, isSymlink := m.symlinks[name]; isSymlink {
		return true, nil
	}
	if _, isDir := m.dirs[name]; isDir {
		return false, nil
	}
	if _, isFile := m.files[name]; isFile {
		return false, nil
	}
	return false, os.ErrNotExist
}

func (m *mockFs) Glob(pattern string, excludes []string, follow ShouldFollowSymlinks) (matches, dirs []string, err error) {
	return startGlob(m, pattern, excludes, follow)
}

func unescapeGlob(s string) string {
	i := 0
	for i < len(s) {
		if s[i] == '\\' {
			s = s[:i] + s[i+1:]
		} else {
			i++
		}
	}
	return s
}

func (m *mockFs) glob(pattern string) ([]string, error) {
	dir, file := saneSplit(pattern)

	dir = unescapeGlob(dir)
	toDir := m.followSymlinks(dir)

	var matches []string
	for _, f := range m.all {
		fDir, fFile := saneSplit(f)
		if toDir == fDir {
			match, err := filepath.Match(file, fFile)
			if err != nil {
				return nil, err
			}
			if (f == "." || f == "/") && f != pattern {
				// filepath.Glob won't return "." or "/" unless the pattern was "." or "/"
				match = false
			}
			if match {
				matches = append(matches, filepath.Join(dir, fFile))
			}
		}
	}
	return matches, nil
}

type mockStat struct {
	name string
	size int64
	mode os.FileMode
}

func (ms *mockStat) Name() string       { return ms.name }
func (ms *mockStat) IsDir() bool        { return ms.Mode().IsDir() }
func (ms *mockStat) Size() int64        { return ms.size }
func (ms *mockStat) Mode() os.FileMode  { return ms.mode }
func (ms *mockStat) ModTime() time.Time { return time.Time{} }
func (ms *mockStat) Sys() interface{}   { return nil }

func (m *mockFs) Lstat(name string) (os.FileInfo, error) {
	dir, file := saneSplit(name)
	dir = m.followSymlinks(dir)
	name = filepath.Join(dir, file)

	ms := mockStat{
		name: file,
	}

	if symlink, isSymlink := m.symlinks[name]; isSymlink {
		ms.mode = os.ModeSymlink
		ms.size = int64(len(symlink))
	} else if _, isDir := m.dirs[name]; isDir {
		ms.mode = os.ModeDir
	} else if _, isFile := m.files[name]; isFile {
		ms.mode = 0
		ms.size = int64(len(m.files[name]))
	} else {
		return nil, os.ErrNotExist
	}

	return &ms, nil
}

func (m *mockFs) Stat(name string) (os.FileInfo, error) {
	name = filepath.Clean(name)
	origName := name
	name = m.followSymlinks(name)

	ms := mockStat{
		name: filepath.Base(origName),
		size: int64(len(m.files[name])),
	}

	if _, isDir := m.dirs[name]; isDir {
		ms.mode = os.ModeDir
	} else if _, isFile := m.files[name]; isFile {
		ms.mode = 0
		ms.size = int64(len(m.files[name]))
	} else {
		return nil, os.ErrNotExist
	}

	return &ms, nil
}

func (m *mockFs) ReadDirNames(name string) ([]string, error) {
	name = filepath.Clean(name)
	name = m.followSymlinks(name)

	exists, isDir, err := m.Exists(name)
	if err != nil {
		return nil, err
	}
	if !exists {
		return nil, os.ErrNotExist
	}
	if !isDir {
		return nil, os.NewSyscallError("readdir", syscall.ENOTDIR)
	}

	var ret []string
	for _, f := range m.all {
		dir, file := saneSplit(f)
		if dir == name && len(file) > 0 && file[0] != '.' {
			ret = append(ret, file)
		}
	}
	return ret, nil
}

func (m *mockFs) ListDirsRecursive(name string, follow ShouldFollowSymlinks) ([]string, error) {
	return listDirsRecursive(m, name, follow)
}

func (m *mockFs) Readlink(name string) (string, error) {
	dir, file := saneSplit(name)
	dir = m.followSymlinks(dir)

	origName := name
	name = filepath.Join(dir, file)

	if dest, isSymlink := m.symlinks[name]; isSymlink {
		return dest, nil
	}

	if exists, _, err := m.Exists(name); err != nil {
		return "", err
	} else if !exists {
		return "", os.ErrNotExist
	} else {
		return "", os.NewSyscallError("readlink: "+origName, syscall.EINVAL)
	}
}

func listDirsRecursive(fs FileSystem, name string, follow ShouldFollowSymlinks) ([]string, error) {
	name = filepath.Clean(name)

	isDir, err := fs.IsDir(name)
	if err != nil {
		return nil, err
	}

	if !isDir {
		return nil, nil
	}

	dirs := []string{name}

	subDirs, err := listDirsRecursiveRelative(fs, name, follow, 0)
	if err != nil {
		return nil, err
	}

	for _, d := range subDirs {
		dirs = append(dirs, filepath.Join(name, d))
	}

	return dirs, nil
}

func listDirsRecursiveRelative(fs FileSystem, name string, follow ShouldFollowSymlinks, depth int) ([]string, error) {
	depth++
	if depth > 255 {
		return nil, fmt.Errorf("too many symlinks")
	}
	contents, err := fs.ReadDirNames(name)
	if err != nil {
		return nil, err
	}

	var dirs []string
	for _, f := range contents {
		if f[0] == '.' {
			continue
		}
		f = filepath.Join(name, f)
		if isSymlink, _ := fs.IsSymlink(f); isSymlink && follow == DontFollowSymlinks {
			continue
		}
		if isDir, _ := fs.IsDir(f); isDir {
			dirs = append(dirs, f)
			subDirs, err := listDirsRecursiveRelative(fs, f, follow, depth)
			if err != nil {
				return nil, err
			}
			for _, s := range subDirs {
				dirs = append(dirs, filepath.Join(f, s))
			}
		}
	}

	for i, d := range dirs {
		rel, err := filepath.Rel(name, d)
		if err != nil {
			return nil, err
		}
		dirs[i] = rel
	}

	return dirs, nil
}
