// 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.

// Experimental Go package installer; see doc.go.

package main

import (
	"bytes"
	"exec"
	"flag"
	"fmt"
	"io"
	"os"
	"path"
	"runtime"
	"strings"
)

func usage() {
	fmt.Fprint(os.Stderr, "usage: goinstall importpath...\n")
	flag.PrintDefaults()
	os.Exit(2)
}

var (
	argv0   = os.Args[0]
	errors  = false
	gobin   = os.Getenv("GOBIN")
	parents = make(map[string]string)
	root    = runtime.GOROOT()
	visit   = make(map[string]status)

	reportToDashboard = flag.Bool("dashboard", true, "report public packages at "+dashboardURL)
	update            = flag.Bool("u", false, "update already-downloaded packages")
	verbose           = flag.Bool("v", false, "verbose")
)

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

func main() {
	flag.Usage = usage
	flag.Parse()
	if root == "" {
		fmt.Fprintf(os.Stderr, "%s: no $GOROOT\n", argv0)
		os.Exit(1)
	}
	if gobin == "" {
		gobin = root + "/bin"
	}
	root += "/src/pkg/"

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

	// install command line arguments
	args := flag.Args()
	if len(args) == 0 {
		usage()
	}
	for _, path := range args {
		install(path, "")
	}
	if errors {
		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)
}

// install installs the package named by path, which is needed by parent.
func install(pkg, parent string) {
	// Make sure we're not already trying to install pkg.
	switch visit[pkg] {
	case done:
		return
	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)
	}
	visit[pkg] = visiting
	parents[pkg] = parent
	if *verbose {
		fmt.Println(pkg)
	}

	// Check whether package is local or remote.
	// If remote, download or update it.
	var dir string
	local := false
	if isLocalPath(pkg) {
		dir = pkg
		local = true
	} else if isStandardPath(pkg) {
		dir = path.Join(root, pkg)
		local = true
	} else {
		var err os.Error
		dir, err = download(pkg)
		if err != nil {
			fmt.Fprintf(os.Stderr, "%s: %s: %s\n", argv0, pkg, err)
			errors = true
			visit[pkg] = done
			return
		}
	}

	// Install prerequisites.
	files, m, pkgname, err := goFiles(dir, parent == "")
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s: %s: %s\n", argv0, pkg, err)
		errors = true
		visit[pkg] = done
		return
	}
	if len(files) == 0 {
		fmt.Fprintf(os.Stderr, "%s: %s: package has no files\n", argv0, pkg)
		errors = true
		visit[pkg] = done
		return
	}
	for p := range m {
		install(p, pkg)
	}
	if pkgname == "main" {
		if !errors {
			fmt.Fprintf(os.Stderr, "%s: %s's dependencies are installed.\n", argv0, pkg)
		}
		errors = true
		visit[pkg] = done
		return
	}

	// Install this package.
	if !errors {
		if err := domake(dir, pkg, local); err != nil {
			fmt.Fprintf(os.Stderr, "%s: installing %s: %s\n", argv0, pkg, err)
			errors = true
		}
	}

	visit[pkg] = done
}

// Is this a local path?  /foo ./foo ../foo . ..
func isLocalPath(s string) bool {
	return strings.HasPrefix(s, "/") || strings.HasPrefix(s, "./") || strings.HasPrefix(s, "../") || s == "." || s == ".."
}

// Is this a standard package path?  strings container/vector 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 the command fails, run prints the command and output on standard error
// in addition to returning a non-nil os.Error.
func run(dir string, stdin []byte, cmd ...string) os.Error {
	return genRun(dir, stdin, cmd, false)
}

// quietRun is like run but prints nothing on failure unless -v is used.
func quietRun(dir string, stdin []byte, cmd ...string) os.Error {
	return genRun(dir, stdin, cmd, true)
}

// genRun implements run and quietRun.
func genRun(dir string, stdin []byte, cmd []string, quiet bool) os.Error {
	bin, err := exec.LookPath(cmd[0])
	if err != nil {
		// report binary as well as the error
		return os.NewError(cmd[0] + ": " + err.String())
	}
	p, err := exec.Run(bin, cmd, os.Environ(), dir, exec.Pipe, exec.Pipe, exec.MergeWithStdout)
	if *verbose {
		fmt.Fprintf(os.Stderr, "%s: %s; %s %s\n", argv0, dir, bin, strings.Join(cmd[1:], " "))
	}
	if err != nil {
		return err
	}
	go func() {
		p.Stdin.Write(stdin)
		p.Stdin.Close()
	}()
	var buf bytes.Buffer
	io.Copy(&buf, p.Stdout)
	io.Copy(&buf, p.Stdout)
	w, err := p.Wait(0)
	p.Close()
	if err != nil {
		return err
	}
	if !w.Exited() || w.ExitStatus() != 0 {
		if !quiet || *verbose {
			if dir != "" {
				dir = "cd " + dir + "; "
			}
			fmt.Fprintf(os.Stderr, "%s: === %s%s\n", argv0, dir, strings.Join(cmd, " "))
			os.Stderr.Write(buf.Bytes())
			fmt.Fprintf(os.Stderr, "--- %s\n", w)
		}
		return os.ErrorString("running " + cmd[0] + ": " + w.String())
	}
	return nil
}
