// Copyright (c) 2018, Google Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

//go:build ignore

// godeps prints out dependencies of a package in either CMake or Make depfile
// format, for incremental rebuilds.
//
// The depfile format is preferred. It works correctly when new files are added.
// However, CMake only supports depfiles for custom commands with Ninja and
// starting CMake 3.7. For other configurations, we also support CMake's format,
// but CMake must be rerun when file lists change.
package main

import (
	"flag"
	"fmt"
	"go/build"
	"os"
	"path/filepath"
	"sort"
	"strings"
)

var (
	format  = flag.String("format", "cmake", "The format to output to, either 'cmake' or 'depfile'")
	mainPkg = flag.String("pkg", "", "The package to print dependencies for")
	target  = flag.String("target", "", "The name of the output file")
	out     = flag.String("out", "", "The path to write the output to. If unset, this is stdout")
)

func cMakeQuote(in string) string {
	// See https://cmake.org/cmake/help/v3.0/manual/cmake-language.7.html#quoted-argument
	var b strings.Builder
	b.Grow(len(in))
	// Iterate over in as bytes.
	for i := 0; i < len(in); i++ {
		switch c := in[i]; c {
		case '\\', '"':
			b.WriteByte('\\')
			b.WriteByte(c)
		case '\t':
			b.WriteString("\\t")
		case '\r':
			b.WriteString("\\r")
		case '\n':
			b.WriteString("\\n")
		default:
			b.WriteByte(in[i])
		}
	}
	return b.String()
}

func writeCMake(outFile *os.File, files []string) error {
	for i, file := range files {
		if i != 0 {
			if _, err := outFile.WriteString(";"); err != nil {
				return err
			}
		}
		if _, err := outFile.WriteString(cMakeQuote(file)); err != nil {
			return err
		}
	}
	return nil
}

func makeQuote(in string) string {
	// See https://www.gnu.org/software/make/manual/make.html#Rule-Syntax
	var b strings.Builder
	b.Grow(len(in))
	// Iterate over in as bytes.
	for i := 0; i < len(in); i++ {
		switch c := in[i]; c {
		case '$':
			b.WriteString("$$")
		case '#', '\\', ' ':
			b.WriteByte('\\')
			b.WriteByte(c)
		default:
			b.WriteByte(c)
		}
	}
	return b.String()
}

func writeDepfile(outFile *os.File, files []string) error {
	if _, err := fmt.Fprintf(outFile, "%s:", makeQuote(*target)); err != nil {
		return err
	}
	for _, file := range files {
		if _, err := fmt.Fprintf(outFile, " %s", makeQuote(file)); err != nil {
			return err
		}
	}
	_, err := outFile.WriteString("\n")
	return err
}

func appendPrefixed(list, newFiles []string, prefix string) []string {
	for _, file := range newFiles {
		list = append(list, filepath.Join(prefix, file))
	}
	return list
}

func main() {
	flag.Parse()

	if len(*mainPkg) == 0 {
		fmt.Fprintf(os.Stderr, "-pkg argument is required.\n")
		os.Exit(1)
	}

	var isDepfile bool
	switch *format {
	case "depfile":
		isDepfile = true
	case "cmake":
		isDepfile = false
	default:
		fmt.Fprintf(os.Stderr, "Unknown format: %q\n", *format)
		os.Exit(1)
	}

	if isDepfile && len(*target) == 0 {
		fmt.Fprintf(os.Stderr, "-target argument is required for depfile.\n")
		os.Exit(1)
	}

	done := make(map[string]struct{})
	var files []string
	var recurse func(pkgName string) error
	recurse = func(pkgName string) error {
		pkg, err := build.Default.Import(pkgName, ".", 0)
		if err != nil {
			return err
		}

		// Skip standard packages.
		if pkg.Goroot {
			return nil
		}

		// Skip already-visited packages.
		if _, ok := done[pkg.Dir]; ok {
			return nil
		}
		done[pkg.Dir] = struct{}{}

		files = appendPrefixed(files, pkg.GoFiles, pkg.Dir)
		files = appendPrefixed(files, pkg.CgoFiles, pkg.Dir)
		// Include ignored Go files. A subsequent change may cause them
		// to no longer be ignored.
		files = appendPrefixed(files, pkg.IgnoredGoFiles, pkg.Dir)

		// Recurse into imports.
		for _, importName := range pkg.Imports {
			if err := recurse(importName); err != nil {
				return err
			}
		}
		return nil
	}
	if err := recurse(*mainPkg); err != nil {
		fmt.Fprintf(os.Stderr, "Error getting dependencies: %s\n", err)
		os.Exit(1)
	}

	sort.Strings(files)

	outFile := os.Stdout
	if len(*out) != 0 {
		var err error
		outFile, err = os.Create(*out)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error writing output: %s\n", err)
			os.Exit(1)
		}
		defer outFile.Close()
	}

	var err error
	if isDepfile {
		err = writeDepfile(outFile, files)
	} else {
		err = writeCMake(outFile, files)
	}
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error writing output: %s\n", err)
		os.Exit(1)
	}
}
