// package fileutils provides utililty methods to copy and move files and directories.
package fileutils

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime"
	"strings"
)

// https://golang.org/cmd/go/#hdr-File_types
var goFileTypes = []string{
	".go",
	".c", ".h",
	".cc", ".cpp", ".cxx", ".hh", ".hpp", ".hxx",
	".m",
	".s", ".S",
	".swig", ".swigcxx",
	".syso",
}

var licenseFiles = []string{
	"LICENSE", "LICENCE", "UNLICENSE", "COPYING", "COPYRIGHT",
}

// Copypath copies the contents of src to dst, excluding any file that is not
// relevant to the Go compiler.
func Copypath(dst string, src string, tests bool) error {
	err := filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		name := filepath.Base(path)

		relevantFile := false
		for _, ext := range goFileTypes {
			if strings.HasSuffix(name, ext) {
				relevantFile = true
				break
			}
		}

		testdata := false
		for _, n := range strings.Split(filepath.Dir(path), string(filepath.Separator)) {
			if n == "testdata" || n == "_testdata" {
				testdata = true
			}
		}

		skip := false
		switch {
		// Include all files in a testdata folder
		case tests && testdata:
			skip = false

		// https://golang.org/cmd/go/#hdr-Description_of_package_lists
		case strings.HasPrefix(name, "."):
			skip = true
		case strings.HasPrefix(name, "_") && name != "_testdata":
			skip = true

		case !tests && name == "_testdata" && info.IsDir():
			skip = true
		case !tests && name == "testdata" && info.IsDir():
			skip = true
		case !tests && strings.HasSuffix(name, "_test.go") && !info.IsDir():
			skip = true

		case !relevantFile && !info.IsDir():
			skip = true
		}

		if skip {
			if info.IsDir() {
				return filepath.SkipDir
			}
			return nil
		}

		if info.IsDir() {
			return nil
		}

		dst := filepath.Join(dst, path[len(src):])

		if info.Mode()&os.ModeSymlink != 0 {
			return Copylink(dst, path)
		}

		return Copyfile(dst, path)
	})
	if err != nil {
		// if there was an error during copying, remove the partial copy.
		RemoveAll(dst)
	}
	return err
}

func Copyfile(dst, src string) error {
	err := mkdir(filepath.Dir(dst))
	if err != nil {
		return fmt.Errorf("copyfile: mkdirall: %v", err)
	}
	r, err := os.Open(src)
	if err != nil {
		return fmt.Errorf("copyfile: open(%q): %v", src, err)
	}
	defer r.Close()
	w, err := os.Create(dst)
	if err != nil {
		return fmt.Errorf("copyfile: create(%q): %v", dst, err)
	}
	defer w.Close()
	_, err = io.Copy(w, r)
	return err
}

func Copylink(dst, src string) error {
	target, err := os.Readlink(src)
	if err != nil {
		return fmt.Errorf("copylink: readlink: %v", err)
	}
	if err := mkdir(filepath.Dir(dst)); err != nil {
		return fmt.Errorf("copylink: mkdirall: %v", err)
	}
	if err := os.Symlink(target, dst); err != nil {
		return fmt.Errorf("copylink: symlink: %v", err)
	}
	return nil
}

// RemoveAll removes path and any children it contains. Unlike os.RemoveAll it
// deletes read only files on Windows.
func RemoveAll(path string) error {
	if runtime.GOOS == "windows" {
		// Simple case: if Remove works, we're done.
		err := os.Remove(path)
		if err == nil || os.IsNotExist(err) {
			return nil
		}
		// make sure all files are writable so we can delete them
		filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
			if err != nil {
				// walk gave us some error, give it back.
				return err
			}
			mode := info.Mode()
			if mode|0200 == mode {
				return nil
			}
			return os.Chmod(path, mode|0200)
		})
	}
	return os.RemoveAll(path)
}

// CopyLicense copies the license file from folder src to folder dst.
func CopyLicense(dst, src string) error {
	files, err := ioutil.ReadDir(src)
	if err != nil {
		return err
	}
	for _, f := range files {
		if f.IsDir() {
			continue
		}
		name := filepath.Base(f.Name())
		for _, candidate := range licenseFiles {
			if strings.ToLower(candidate) == strings.TrimSuffix(
				strings.TrimSuffix(strings.ToLower(name), ".md"), ".txt") {
				return Copyfile(filepath.Join(dst, name), f.Name())
			}
		}
	}
	return nil
}

func mkdir(path string) error {
	return os.MkdirAll(path, 0755)
}
