// Copyright 2022 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package fileutils

import (
	"fmt"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"

	"dawn.googlesource.com/dawn/tools/src/oswrapper"
)

// ThisLine returns the filepath and line number of the calling function
func ThisLine() string {
	_, file, line, ok := runtime.Caller(1)
	if !ok {
		return ""
	}
	return fmt.Sprintf("%v:%v", file, line)
}

// ThisDir returns the directory of the caller function
func ThisDir() string {
	_, file, _, ok := runtime.Caller(1)
	if !ok {
		return ""
	}
	return filepath.Dir(file)
}

// DawnRoot returns the path to the dawn project's root directory or empty
// string if not found.
func DawnRoot(fsReader oswrapper.FilesystemReader) string {
	return pathOfFileInParentDirs(ThisDir(), "DEPS", fsReader)
}

// pathOfFileInParentDirs looks for file with `name` in paths starting from
// `path`, and up into parent directories, returning the clean path in which the
// file is found, or empty string if not found.
func pathOfFileInParentDirs(path string, name string, fsReader oswrapper.FilesystemReader) string {
	sep := string(filepath.Separator)
	path, _ = filepath.Abs(path)
	numDirs := strings.Count(path, sep) + 1
	for i := 0; i < numDirs; i++ {
		test := filepath.Join(path, name)
		if _, err := fsReader.Stat(test); err == nil {
			return filepath.Clean(path)
		}

		path = path + sep + ".."
	}
	return ""
}

// ExpandHome returns the string with all occurrences of '~' replaced with the
// user's home directory. If the user's home directory cannot be found, then
// the input string is returned.
func ExpandHome(path string, environProvider oswrapper.EnvironProvider) string {
	if strings.ContainsRune(path, '~') {
		if home, err := environProvider.UserHomeDir(); err == nil {
			return strings.ReplaceAll(path, "~", home)
		}
	}
	return path
}

// TODO(crbug.com/416755658): Add unittest coverage once exec is handled via
// dependency injection.
// NodePath looks for the node binary, first in dawn's third_party directory,
// falling back to PATH.
func NodePath(fsReader oswrapper.FilesystemReader) string {
	if dawnRoot := DawnRoot(fsReader); dawnRoot != "" {
		node := filepath.Join(dawnRoot, "third_party", "node")
		if info, err := fsReader.Stat(node); err == nil && info.IsDir() {
			path := ""
			switch fmt.Sprintf("%v/%v", runtime.GOOS, runtime.GOARCH) { // See `go tool dist list`
			case "darwin/amd64":
				path = filepath.Join(node, "mac-amd64", "bin", "node")
			case "darwin/arm64":
				path = filepath.Join(node, "mac-arm64", "bin", "node")
			case "linux/amd64":
				path = filepath.Join(node, "linux-amd64", "bin", "node")
			case "linux/arm64":
				path = filepath.Join(node, "linux-arm64", "bin", "node")
			case "windows/amd64":
				path = filepath.Join(node, "windows-amd64", "node.exe")
			case "windows/arm64":
				path = filepath.Join(node, "windows-arm64", "node.exe")
			}
			if _, err := fsReader.Stat(path); err == nil {
				return path
			}
		}
	}

	if path, err := exec.LookPath("node"); err == nil {
		return path
	}

	return ""
}

// BuildPath looks for the binary output directory at '<dawn>/out/active'.
// Returns the path if found, otherwise an empty string.
func BuildPath(fsReader oswrapper.FilesystemReader) string {
	if dawnRoot := DawnRoot(fsReader); dawnRoot != "" {
		bin := filepath.Join(dawnRoot, "out", "active")
		if info, err := fsReader.Stat(bin); err == nil && info.IsDir() {
			return bin
		}
	}
	return ""
}

// IsDir returns true if the path resolves to a directory
func IsDir(path string, fsReader oswrapper.FilesystemReader) bool {
	s, err := fsReader.Stat(path)
	if err != nil {
		return false
	}
	return s.IsDir()
}

// IsFile returns true if the path resolves to a file
func IsFile(path string, fsReader oswrapper.FilesystemReader) bool {
	s, err := fsReader.Stat(path)
	if err != nil {
		return false
	}
	return !s.IsDir()
}

// CommonRootDir returns the common directory for pathA and pathB
func CommonRootDir(pathA, pathB string) string {
	pathA, pathB = filepath.ToSlash(pathA), filepath.ToSlash(pathB) // Normalize to forward-slash
	if !strings.HasSuffix(pathA, "/") {
		pathA += "/"
	}
	if !strings.HasSuffix(pathB, "/") {
		pathB += "/"
	}
	n := len(pathA)
	if len(pathB) < n {
		n = len(pathB)
	}
	common := ""
	for i := 0; i < n; i++ {
		a, b := pathA[i], pathB[i]
		if a != b {
			break
		}
		if a == '/' {
			common = pathA[:i+1]
		}
	}
	return common
}

// IsEmptyDir returns true if the directory at 'dir' contains no files or
// subdirectories. Returns an error if the path does not exist or is not a
// directory.
func IsEmptyDir(dir string, fsReader oswrapper.FilesystemReader) (bool, error) {
	info, err := fsReader.Stat(dir)
	if err != nil {
		return false, fmt.Errorf("failed to stat '%s': %w", dir, err)
	}
	if !info.IsDir() {
		return false, fmt.Errorf("path is not a directory: %s", dir)
	}

	entries, err := fsReader.ReadDir(dir)
	if err != nil {
		return false, fmt.Errorf("failed to read directory '%s': %w", dir, err)
	}

	return len(entries) == 0, nil
}
