package copy

import (
	"io"
	"os"
	"path/filepath"
	"strings"
)

// CopyDir recursively copies all of the files within the directory given in
// src to the directory given in dst.
//
// Both directories should already exist. If the destination directory is
// non-empty then the new files will merge in with the old, overwriting any
// files that have a relative path in common between source and destination.
//
// Recursive copying of directories is inevitably a rather opinionated sort of
// operation, so this function won't be appropriate for all use-cases. Some
// of the "opinions" it has are described in the following paragraphs:
//
// Symlinks in the source directory are recreated with the same target in the
// destination directory. If the symlink is to a directory itself, that
// directory is not recursively visited for further copying.
//
// File and directory modes are not preserved exactly, but the executable
// flag is preserved for files on operating systems where it is significant.
//
// Any "dot files" it encounters along the way are skipped, even on platforms
// that do not normally ascribe special meaning to files with names starting
// with dots.
//
// Callers may rely on the above details and other undocumented details of
// this function, so if you intend to change it be sure to review the callers
// first and make sure they are compatible with the change you intend to make.
func CopyDir(dst, src string) error {
	src, err := filepath.EvalSymlinks(src)
	if err != nil {
		return err
	}

	walkFn := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if path == src {
			return nil
		}

		if strings.HasPrefix(filepath.Base(path), ".") {
			// Skip any dot files
			if info.IsDir() {
				return filepath.SkipDir
			} else {
				return nil
			}
		}

		// The "path" has the src prefixed to it. We need to join our
		// destination with the path without the src on it.
		dstPath := filepath.Join(dst, path[len(src):])

		// we don't want to try and copy the same file over itself.
		if eq, err := SameFile(path, dstPath); eq {
			return nil
		} else if err != nil {
			return err
		}

		// If we have a directory, make that subdirectory, then continue
		// the walk.
		if info.IsDir() {
			if path == filepath.Join(src, dst) {
				// dst is in src; don't walk it.
				return nil
			}

			if err := os.MkdirAll(dstPath, 0755); err != nil {
				return err
			}

			return nil
		}

		// If the current path is a symlink, recreate the symlink relative to
		// the dst directory
		if info.Mode()&os.ModeSymlink == os.ModeSymlink {
			target, err := os.Readlink(path)
			if err != nil {
				return err
			}

			return os.Symlink(target, dstPath)
		}

		// If we have a file, copy the contents.
		srcF, err := os.Open(path)
		if err != nil {
			return err
		}
		defer srcF.Close()

		dstF, err := os.Create(dstPath)
		if err != nil {
			return err
		}
		defer dstF.Close()

		if _, err := io.Copy(dstF, srcF); err != nil {
			return err
		}

		// Chmod it
		return os.Chmod(dstPath, info.Mode())
	}

	return filepath.Walk(src, walkFn)
}

// SameFile returns true if the two given paths refer to the same physical
// file on disk, using the unique file identifiers from the underlying
// operating system. For example, on Unix systems this checks whether the
// two files are on the same device and have the same inode.
func SameFile(a, b string) (bool, error) {
	if a == b {
		return true, nil
	}

	aInfo, err := os.Lstat(a)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, err
	}

	bInfo, err := os.Lstat(b)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, err
	}

	return os.SameFile(aInfo, bInfo), nil
}
