// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"errors"
	"flag"
	"fmt"
	"go/build"
	"go/token"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath" // use for file system paths
	"regexp"
	"runtime"
	"strings"
)

func usage() {
	fmt.Fprintln(os.Stderr, "usage: goinstall [flags] importpath...")
	fmt.Fprintln(os.Stderr, "       goinstall [flags] -a")
	flag.PrintDefaults()
	os.Exit(2)
}

const logfile = "goinstall.log"

var (
	fset          = token.NewFileSet()
	argv0         = os.Args[0]
	parents       = make(map[string]string)
	visit         = make(map[string]status)
	installedPkgs = make(map[string]map[string]bool)
	schemeRe      = regexp.MustCompile(`^[a-z]+://`)

	allpkg            = flag.Bool("a", false, "install all previously installed packages")
	reportToDashboard = flag.Bool("dashboard", true, "report public packages at "+dashboardURL)
	update            = flag.Bool("u", false, "update already-downloaded packages")
	doGofix           = flag.Bool("fix", false, "gofix each package before building it")
	doInstall         = flag.Bool("install", true, "build and install")
	clean             = flag.Bool("clean", false, "clean the package directory before installing")
	nuke              = flag.Bool("nuke", false, "clean the package directory and target before installing")
	useMake           = flag.Bool("make", true, "use make to build and install")
	verbose           = flag.Bool("v", false, "verbose")
)

type status int // status for visited map
const (
	unvisited status = iota
	visiting
	done
)

type PackageError struct {
	pkg string
	err error
}

func (e *PackageError) Error() string {
	return fmt.Sprintf("%s: %v", e.pkg, e.err)
}

type DownloadError struct {
	pkg    string
	goroot bool
	err    error
}

func (e *DownloadError) Error() string {
	s := fmt.Sprintf("%s: download failed: %v", e.pkg, e.err)
	if e.goroot && os.Getenv("GOPATH") == "" {
		s += " ($GOPATH is not set)"
	}
	return s
}

type DependencyError PackageError

func (e *DependencyError) Error() string {
	return fmt.Sprintf("%s: depends on failing packages:\n\t%v", e.pkg, e.err)
}

type BuildError PackageError

func (e *BuildError) Error() string {
	return fmt.Sprintf("%s: build failed: %v", e.pkg, e.err)
}

type RunError struct {
	cmd, dir string
	out      []byte
	err      error
}

func (e *RunError) Error() string {
	return fmt.Sprintf("%v\ncd %q && %q\n%s", e.err, e.dir, e.cmd, e.out)
}

func logf(format string, args ...interface{}) {
	format = "%s: " + format
	args = append([]interface{}{argv0}, args...)
	fmt.Fprintf(os.Stderr, format, args...)
}

func printf(format string, args ...interface{}) {
	if *verbose {
		logf(format, args...)
	}
}

func main() {
	flag.Usage = usage
	flag.Parse()
	if runtime.GOROOT() == "" {
		fmt.Fprintf(os.Stderr, "%s: no $GOROOT\n", argv0)
		os.Exit(1)
	}
	readPackageList()

	// special case - "unsafe" is already installed
	visit["unsafe"] = done

	args := flag.Args()
	if *allpkg {
		if len(args) != 0 {
			usage() // -a and package list both provided
		}
		// install all packages that were ever installed
		n := 0
		for _, pkgs := range installedPkgs {
			for pkg := range pkgs {
				args = append(args, pkg)
				n++
			}
		}
		if n == 0 {
			logf("no installed packages\n")
			os.Exit(1)
		}
	}
	if len(args) == 0 {
		usage()
	}
	errs := false
	for _, path := range args {
		if err := install(path, ""); err != nil {
			errs = true
			fmt.Fprintln(os.Stderr, err)
		}
	}
	if errs {
		os.Exit(1)
	}
}

// printDeps prints the dependency path that leads to pkg.
func printDeps(pkg string) {
	if pkg == "" {
		return
	}
	if visit[pkg] != done {
		printDeps(parents[pkg])
	}
	fmt.Fprintf(os.Stderr, "\t%s ->\n", pkg)
}

// readPackageList reads the list of installed packages from the
// goinstall.log files in GOROOT and the GOPATHs and initializes
// the installedPkgs variable.
func readPackageList() {
	for _, t := range build.Path {
		installedPkgs[t.Path] = make(map[string]bool)
		name := filepath.Join(t.Path, logfile)
		pkglistdata, err := ioutil.ReadFile(name)
		if err != nil {
			printf("%s\n", err)
			continue
		}
		pkglist := strings.Fields(string(pkglistdata))
		for _, pkg := range pkglist {
			installedPkgs[t.Path][pkg] = true
		}
	}
}

// logPackage logs the named package as installed in the goinstall.log file
// in the given tree if the package is not already in that file.
func logPackage(pkg string, tree *build.Tree) (logged bool) {
	if installedPkgs[tree.Path][pkg] {
		return false
	}
	name := filepath.Join(tree.Path, logfile)
	fout, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		printf("package log: %s\n", err)
		return false
	}
	fmt.Fprintf(fout, "%s\n", pkg)
	fout.Close()
	return true
}

// install installs the package named by path, which is needed by parent.
func install(pkg, parent string) error {
	// Basic validation of import path string.
	if s := schemeRe.FindString(pkg); s != "" {
		return fmt.Errorf("%q used in import path, try %q\n", s, pkg[len(s):])
	}
	if strings.HasSuffix(pkg, "/") {
		return fmt.Errorf("%q should not have trailing '/'\n", pkg)
	}

	// Make sure we're not already trying to install pkg.
	switch visit[pkg] {
	case done:
		return nil
	case visiting:
		fmt.Fprintf(os.Stderr, "%s: package dependency cycle\n", argv0)
		printDeps(parent)
		fmt.Fprintf(os.Stderr, "\t%s\n", pkg)
		os.Exit(2)
	}
	parents[pkg] = parent
	visit[pkg] = visiting
	defer func() {
		visit[pkg] = done
	}()

	// Check whether package is local or remote.
	// If remote, download or update it.
	tree, pkg, err := build.FindTree(pkg)
	// Don't build the standard library.
	if err == nil && tree.Goroot && isStandardPath(pkg) {
		if parent == "" {
			return &PackageError{pkg, errors.New("cannot goinstall the standard library")}
		}
		return nil
	}

	// Download remote packages if not found or forced with -u flag.
	remote, public := isRemote(pkg), false
	if remote {
		if err == build.ErrNotFound || (err == nil && *update) {
			// Download remote package.
			printf("%s: download\n", pkg)
			public, err = download(pkg, tree.SrcDir())
			if err != nil {
				return &DownloadError{pkg, tree.Goroot, err}
			}
		} else {
			// Test if this is a public repository
			// (for reporting to dashboard).
			repo, e := findPublicRepo(pkg)
			public = repo != nil
			err = e
		}
	}
	if err != nil {
		return &PackageError{pkg, err}
	}

	// Install the package and its dependencies.
	if err := installPackage(pkg, parent, tree, false); err != nil {
		return err
	}

	if remote {
		// mark package as installed in goinstall.log
		logged := logPackage(pkg, tree)

		// report installation to the dashboard if this is the first
		// install from a public repository.
		if logged && public {
			maybeReportToDashboard(pkg)
		}
	}

	return nil
}

// installPackage installs the specified package and its dependencies.
func installPackage(pkg, parent string, tree *build.Tree, retry bool) (installErr error) {
	printf("%s: install\n", pkg)

	// Read package information.
	dir := filepath.Join(tree.SrcDir(), filepath.FromSlash(pkg))
	dirInfo, err := build.ScanDir(dir)
	if err != nil {
		return &PackageError{pkg, err}
	}

	// We reserve package main to identify commands.
	if parent != "" && dirInfo.Package == "main" {
		return &PackageError{pkg, fmt.Errorf("found only package main in %s; cannot import", dir)}
	}

	// Run gofix if we fail to build and -fix is set.
	defer func() {
		if retry || installErr == nil || !*doGofix {
			return
		}
		if e, ok := (installErr).(*DependencyError); ok {
			// If this package failed to build due to a
			// DependencyError, only attempt to gofix it if its
			// dependency failed for some reason other than a
			// DependencyError or BuildError.
			// (If a dep or one of its deps doesn't build there's
			// no way that gofixing this package can help.)
			switch e.err.(type) {
			case *DependencyError:
				return
			case *BuildError:
				return
			}
		}
		gofix(pkg, dir, dirInfo)
		installErr = installPackage(pkg, parent, tree, true) // retry
	}()

	// Install prerequisites.
	for _, p := range dirInfo.Imports {
		if p == "C" {
			continue
		}
		if err := install(p, pkg); err != nil {
			return &DependencyError{pkg, err}
		}
	}

	// Install this package.
	if *useMake {
		err := domake(dir, pkg, tree, dirInfo.IsCommand())
		if err != nil {
			return &BuildError{pkg, err}
		}
		return nil
	}
	script, err := build.Build(tree, pkg, dirInfo)
	if err != nil {
		return &BuildError{pkg, err}
	}
	if *nuke {
		printf("%s: nuke\n", pkg)
		script.Nuke()
	} else if *clean {
		printf("%s: clean\n", pkg)
		script.Clean()
	}
	if *doInstall {
		if script.Stale() {
			printf("%s: install\n", pkg)
			if err := script.Run(); err != nil {
				return &BuildError{pkg, err}
			}
		} else {
			printf("%s: up-to-date\n", pkg)
		}
	}

	return nil
}

// gofix runs gofix against the GoFiles and CgoFiles of dirInfo in dir.
func gofix(pkg, dir string, dirInfo *build.DirInfo) {
	printf("%s: gofix\n", pkg)
	files := append([]string{}, dirInfo.GoFiles...)
	files = append(files, dirInfo.CgoFiles...)
	for i, file := range files {
		files[i] = filepath.Join(dir, file)
	}
	cmd := exec.Command("gofix", files...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		logf("%s: gofix: %v", pkg, err)
	}
}

// Is this a standard package path?  strings container/list etc.
// Assume that if the first element has a dot, it's a domain name
// and is not the standard package path.
func isStandardPath(s string) bool {
	dot := strings.Index(s, ".")
	slash := strings.Index(s, "/")
	return dot < 0 || 0 < slash && slash < dot
}

// run runs the command cmd in directory dir with standard input stdin.
// If verbose is set and the command fails it prints the output to stderr.
func run(dir string, stdin []byte, arg ...string) error {
	cmd := exec.Command(arg[0], arg[1:]...)
	cmd.Stdin = bytes.NewBuffer(stdin)
	cmd.Dir = dir
	printf("cd %s && %s %s\n", dir, cmd.Path, strings.Join(arg[1:], " "))
	if out, err := cmd.CombinedOutput(); err != nil {
		if *verbose {
			fmt.Fprintf(os.Stderr, "%v\n%s\n", err, out)
		}
		return &RunError{strings.Join(arg, " "), dir, out, err}
	}
	return nil
}

// isRemote returns true if the first part of the package name looks like a
// hostname - i.e. contains at least one '.' and the last part is at least 2
// characters.
func isRemote(pkg string) bool {
	parts := strings.SplitN(pkg, "/", 2)
	if len(parts) != 2 {
		return false
	}
	parts = strings.Split(parts[0], ".")
	if len(parts) < 2 || len(parts[len(parts)-1]) < 2 {
		return false
	}
	return true
}
