// Copyright 2011 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"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"time"

	"golang.org/x/tools/go/vcs"
)

const (
	codeProject          = "go"
	codePyScript         = "misc/dashboard/googlecode_upload.py"
	gofrontendImportPath = "code.google.com/p/gofrontend"
	mkdirPerm            = 0750
	waitInterval         = 30 * time.Second // time to wait before checking for new revs
	pkgBuildInterval     = 24 * time.Hour   // rebuild packages every 24 hours
)

type Builder struct {
	goroot       *Repo
	name         string
	goos, goarch string
	key          string
	env          builderEnv
	// Last benchmarking workpath. We reuse it, if do successive benchmarks on the same commit.
	lastWorkpath string
}

var (
	doBuild       = flag.Bool("build", true, "Build and test packages")
	doBench       = flag.Bool("bench", false, "Run benchmarks")
	buildroot     = flag.String("buildroot", defaultBuildRoot(), "Directory under which to build")
	dashboard     = flag.String("dashboard", "https://build.golang.org", "Dashboard app base path")
	buildRelease  = flag.Bool("release", false, "Build and upload binary release archives")
	buildRevision = flag.String("rev", "", "Build specified revision and exit")
	buildCmd      = flag.String("cmd", filepath.Join(".", allCmd), "Build command (specify relative to go/src/)")
	buildTool     = flag.String("tool", "go", "Tool to build.")
	gcPath        = flag.String("gcpath", "go.googlesource.com/go", "Path to download gc from")
	gccPath       = flag.String("gccpath", "https://github.com/mirrors/gcc.git", "Path to download gcc from")
	gccOpts       = flag.String("gccopts", "", "Command-line options to pass to `make` when building gccgo")
	benchPath     = flag.String("benchpath", "golang.org/x/benchmarks/bench", "Path to download benchmarks from")
	failAll       = flag.Bool("fail", false, "fail all builds")
	parallel      = flag.Bool("parallel", false, "Build multiple targets in parallel")
	buildTimeout  = flag.Duration("buildTimeout", 60*time.Minute, "Maximum time to wait for builds and tests")
	cmdTimeout    = flag.Duration("cmdTimeout", 10*time.Minute, "Maximum time to wait for an external command")
	benchNum      = flag.Int("benchnum", 5, "Run each benchmark that many times")
	benchTime     = flag.Duration("benchtime", 5*time.Second, "Benchmarking time for a single benchmark run")
	benchMem      = flag.Int("benchmem", 64, "Approx RSS value to aim at in benchmarks, in MB")
	fileLock      = flag.String("filelock", "", "File to lock around benchmaring (synchronizes several builders)")
	verbose       = flag.Bool("v", false, "verbose")
	report        = flag.Bool("report", true, "whether to report results to the dashboard")
	subrepos      = flag.Bool("subrepos", true, "whether to build subrepos")
)

var (
	binaryTagRe = regexp.MustCompile(`^(release\.r|weekly\.)[0-9\-.]+`)
	releaseRe   = regexp.MustCompile(`^release\.r[0-9\-.]+`)
	allCmd      = "all" + suffix
	makeCmd     = "make" + suffix
	naclCmd     = "nacltest.bash" // nacl support is linux only
	raceCmd     = "race" + suffix
	cleanCmd    = "clean" + suffix
	suffix      = defaultSuffix()
	exeExt      = defaultExeExt()

	benchCPU      = CpuList([]int{1})
	benchAffinity = CpuList([]int{})
	benchMutex    *FileMutex // Isolates benchmarks from other activities
)

// CpuList is used as flag.Value for -benchcpu flag.
type CpuList []int

func (cl *CpuList) String() string {
	str := ""
	for _, cpu := range *cl {
		if str == "" {
			str = strconv.Itoa(cpu)
		} else {
			str += fmt.Sprintf(",%v", cpu)
		}
	}
	return str
}

func (cl *CpuList) Set(str string) error {
	*cl = []int{}
	for _, val := range strings.Split(str, ",") {
		val = strings.TrimSpace(val)
		if val == "" {
			continue
		}
		cpu, err := strconv.Atoi(val)
		if err != nil || cpu <= 0 {
			return fmt.Errorf("%v is a bad value for GOMAXPROCS", val)
		}
		*cl = append(*cl, cpu)
	}
	if len(*cl) == 0 {
		*cl = append(*cl, 1)
	}
	return nil
}

func main() {
	flag.Var(&benchCPU, "benchcpu", "Comma-delimited list of GOMAXPROCS values for benchmarking")
	flag.Var(&benchAffinity, "benchaffinity", "Comma-delimited list of affinity values for benchmarking")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s goos-goarch...\n", os.Args[0])
		flag.PrintDefaults()
		os.Exit(2)
	}
	flag.Parse()
	if len(flag.Args()) == 0 {
		flag.Usage()
	}

	vcs.ShowCmd = *verbose
	vcs.Verbose = *verbose

	benchMutex = MakeFileMutex(*fileLock)

	rr, err := repoForTool()
	if err != nil {
		log.Fatal("Error finding repository:", err)
	}
	rootPath := filepath.Join(*buildroot, "goroot")
	goroot := &Repo{
		Path:   rootPath,
		Master: rr,
	}

	// set up work environment, use existing environment if possible
	if goroot.Exists() || *failAll {
		log.Print("Found old workspace, will use it")
	} else {
		if err := os.RemoveAll(*buildroot); err != nil {
			log.Fatalf("Error removing build root (%s): %s", *buildroot, err)
		}
		if err := os.Mkdir(*buildroot, mkdirPerm); err != nil {
			log.Fatalf("Error making build root (%s): %s", *buildroot, err)
		}
		var err error
		goroot, err = RemoteRepo(goroot.Master.Root, rootPath)
		if err != nil {
			log.Fatalf("Error creating repository with url (%s): %s", goroot.Master.Root, err)
		}

		goroot, err = goroot.Clone(goroot.Path, "")
		if err != nil {
			log.Fatal("Error cloning repository:", err)
		}
	}

	// set up builders
	builders := make([]*Builder, len(flag.Args()))
	for i, name := range flag.Args() {
		b, err := NewBuilder(goroot, name)
		if err != nil {
			log.Fatal(err)
		}
		builders[i] = b
	}

	if *failAll {
		failMode(builders)
		return
	}

	// if specified, build revision and return
	if *buildRevision != "" {
		hash, err := goroot.FullHash(*buildRevision)
		if err != nil {
			log.Fatal("Error finding revision: ", err)
		}
		var exitErr error
		for _, b := range builders {
			if err := b.buildHash(hash); err != nil {
				log.Println(err)
				exitErr = err
			}
		}
		if exitErr != nil && !*report {
			// This mode (-report=false) is used for
			// testing Docker images, making sure the
			// environment is correctly configured. For
			// testing, we want a non-zero exit status, as
			// returned by log.Fatal:
			log.Fatal("Build error.")
		}
		return
	}

	if !*doBuild && !*doBench {
		fmt.Fprintf(os.Stderr, "Nothing to do, exiting (specify either -build or -bench or both)\n")
		os.Exit(2)
	}

	// go continuous build mode
	// check for new commits and build them
	benchMutex.RLock()
	for {
		built := false
		t := time.Now()
		if *parallel {
			done := make(chan bool)
			for _, b := range builders {
				go func(b *Builder) {
					done <- b.buildOrBench()
				}(b)
			}
			for _ = range builders {
				built = <-done || built
			}
		} else {
			for _, b := range builders {
				built = b.buildOrBench() || built
			}
		}
		// sleep if there was nothing to build
		benchMutex.RUnlock()
		if !built {
			time.Sleep(waitInterval)
		}
		benchMutex.RLock()
		// sleep if we're looping too fast.
		dt := time.Now().Sub(t)
		if dt < waitInterval {
			time.Sleep(waitInterval - dt)
		}
	}
}

// go continuous fail mode
// check for new commits and FAIL them
func failMode(builders []*Builder) {
	for {
		built := false
		for _, b := range builders {
			built = b.failBuild() || built
		}
		// stop if there was nothing to fail
		if !built {
			break
		}
	}
}

func NewBuilder(goroot *Repo, name string) (*Builder, error) {
	b := &Builder{
		goroot: goroot,
		name:   name,
	}

	// get builderEnv for this tool
	var err error
	if b.env, err = b.builderEnv(name); err != nil {
		return nil, err
	}
	if *report {
		err = b.setKey()
	}
	return b, err
}

func (b *Builder) setKey() error {
	// read keys from keyfile
	fn := ""
	switch runtime.GOOS {
	case "plan9":
		fn = os.Getenv("home")
	case "windows":
		fn = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
	default:
		fn = os.Getenv("HOME")
	}
	fn = filepath.Join(fn, ".gobuildkey")
	if s := fn + "-" + b.name; isFile(s) { // builder-specific file
		fn = s
	}
	c, err := ioutil.ReadFile(fn)
	if err != nil {
		// If the on-disk file doesn't exist, also try the
		// Google Compute Engine metadata.
		if v := gceProjectMetadata("buildkey-" + b.name); v != "" {
			b.key = v
			return nil
		}
		return fmt.Errorf("readKeys %s (%s): %s", b.name, fn, err)
	}
	b.key = string(bytes.TrimSpace(bytes.SplitN(c, []byte("\n"), 2)[0]))
	return nil
}

func gceProjectMetadata(attr string) string {
	client := &http.Client{
		Transport: &http.Transport{
			Dial: (&net.Dialer{
				Timeout:   750 * time.Millisecond,
				KeepAlive: 30 * time.Second,
			}).Dial,
			ResponseHeaderTimeout: 750 * time.Millisecond,
		},
	}
	req, _ := http.NewRequest("GET", "http://metadata.google.internal/computeMetadata/v1/project/attributes/"+attr, nil)
	req.Header.Set("Metadata-Flavor", "Google")
	res, err := client.Do(req)
	if err != nil {
		return ""
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		return ""
	}
	slurp, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return ""
	}
	return string(bytes.TrimSpace(slurp))
}

// builderEnv returns the builderEnv for this buildTool.
func (b *Builder) builderEnv(name string) (builderEnv, error) {
	// get goos/goarch from builder string
	s := strings.SplitN(b.name, "-", 3)
	if len(s) < 2 {
		return nil, fmt.Errorf("unsupported builder form: %s", name)
	}
	b.goos = s[0]
	b.goarch = s[1]

	switch *buildTool {
	case "go":
		return &goEnv{
			goos:   s[0],
			goarch: s[1],
		}, nil
	case "gccgo":
		return &gccgoEnv{}, nil
	default:
		return nil, fmt.Errorf("unsupported build tool: %s", *buildTool)
	}
}

// buildCmd returns the build command to invoke.
// Builders which contain the string '-race' in their
// name will override *buildCmd and return raceCmd.
// Builders which start with "nacl-" will override
// *buildCmd and return naclCmd.
func (b *Builder) buildCmd() string {
	if strings.Contains(b.name, "-race") {
		return raceCmd
	}
	if strings.HasPrefix(b.name, "nacl-") {
		return naclCmd
	}
	return *buildCmd
}

// buildOrBench checks for a new commit for this builder
// and builds or benchmarks it if one is found.
// It returns true if a build/benchmark was attempted.
func (b *Builder) buildOrBench() bool {
	var kinds []string
	if *doBuild {
		kinds = append(kinds, "build-go-commit")
	}
	if *doBench {
		kinds = append(kinds, "benchmark-go-commit")
	}
	kind, hash, benchs, err := b.todo(kinds, "", "")
	if err != nil {
		log.Println(err)
		return false
	}
	if hash == "" {
		return false
	}
	switch kind {
	case "build-go-commit":
		if err := b.buildHash(hash); err != nil {
			log.Println(err)
		}
		return true
	case "benchmark-go-commit":
		if err := b.benchHash(hash, benchs); err != nil {
			log.Println(err)
		}
		return true
	default:
		log.Printf("Unknown todo kind %v", kind)
		return false
	}
}

func (b *Builder) buildHash(hash string) error {
	log.Println(b.name, "building", hash)

	// create place in which to do work
	workpath := filepath.Join(*buildroot, b.name+"-"+hash[:12])
	if err := os.Mkdir(workpath, mkdirPerm); err != nil {
		if err2 := removePath(workpath); err2 != nil {
			return err
		}
		if err := os.Mkdir(workpath, mkdirPerm); err != nil {
			return err
		}
	}
	defer removePath(workpath)

	buildLog, runTime, err := b.buildRepoOnHash(workpath, hash, b.buildCmd())
	if err != nil {
		log.Printf("%s failed at %v: %v", b.name, hash, err)
		// record failure
		return b.recordResult(false, "", hash, "", buildLog, runTime)
	}

	// record success
	if err = b.recordResult(true, "", hash, "", "", runTime); err != nil {
		return fmt.Errorf("recordResult: %s", err)
	}

	if *buildTool == "go" && *subrepos {
		// build sub-repositories
		goRoot := filepath.Join(workpath, *buildTool)
		goPath := workpath
		b.buildSubrepos(goRoot, goPath, hash)
	}

	return nil
}

// buildRepoOnHash clones repo into workpath and builds it.
func (b *Builder) buildRepoOnHash(workpath, hash, cmd string) (buildLog string, runTime time.Duration, err error) {
	// Delete the previous workdir, if necessary
	// (benchmarking code can execute several benchmarks in the same workpath).
	if b.lastWorkpath != "" {
		if b.lastWorkpath == workpath {
			panic("workpath already exists: " + workpath)
		}
		removePath(b.lastWorkpath)
		b.lastWorkpath = ""
	}

	// pull before cloning to ensure we have the revision
	if err = b.goroot.Pull(); err != nil {
		buildLog = err.Error()
		return
	}

	// set up builder's environment.
	srcDir, err := b.env.setup(b.goroot, workpath, hash, b.envv())
	if err != nil {
		buildLog = err.Error()
		return
	}

	// build
	var buildbuf bytes.Buffer
	logfile := filepath.Join(workpath, "build.log")
	f, err := os.Create(logfile)
	if err != nil {
		return err.Error(), 0, err
	}
	defer f.Close()
	w := io.MultiWriter(f, &buildbuf)

	// go's build command is a script relative to the srcDir, whereas
	// gccgo's build command is usually "make check-go" in the srcDir.
	if *buildTool == "go" {
		if !filepath.IsAbs(cmd) {
			cmd = filepath.Join(srcDir, cmd)
		}
	}

	// naive splitting of command from its arguments:
	args := strings.Split(cmd, " ")
	c := exec.Command(args[0], args[1:]...)
	c.Dir = srcDir
	c.Env = b.envv()
	if *verbose {
		c.Stdout = io.MultiWriter(os.Stdout, w)
		c.Stderr = io.MultiWriter(os.Stderr, w)
	} else {
		c.Stdout = w
		c.Stderr = w
	}

	startTime := time.Now()
	err = run(c, runTimeout(*buildTimeout))
	runTime = time.Since(startTime)
	if err != nil {
		fmt.Fprintf(w, "Build complete, duration %v. Result: error: %v\n", runTime, err)
	} else {
		fmt.Fprintf(w, "Build complete, duration %v. Result: success\n", runTime)
	}
	return buildbuf.String(), runTime, err
}

// failBuild checks for a new commit for this builder
// and fails it if one is found.
// It returns true if a build was "attempted".
func (b *Builder) failBuild() bool {
	_, hash, _, err := b.todo([]string{"build-go-commit"}, "", "")
	if err != nil {
		log.Println(err)
		return false
	}
	if hash == "" {
		return false
	}

	log.Printf("fail %s %s\n", b.name, hash)

	if err := b.recordResult(false, "", hash, "", "auto-fail mode run by "+os.Getenv("USER"), 0); err != nil {
		log.Print(err)
	}
	return true
}

func (b *Builder) buildSubrepos(goRoot, goPath, goHash string) {
	for _, pkg := range dashboardPackages("subrepo") {
		// get the latest todo for this package
		_, hash, _, err := b.todo([]string{"build-package"}, pkg, goHash)
		if err != nil {
			log.Printf("buildSubrepos %s: %v", pkg, err)
			continue
		}
		if hash == "" {
			continue
		}

		// build the package
		if *verbose {
			log.Printf("buildSubrepos %s: building %q", pkg, hash)
		}
		buildLog, err := b.buildSubrepo(goRoot, goPath, pkg, hash)
		if err != nil {
			if buildLog == "" {
				buildLog = err.Error()
			}
			log.Printf("buildSubrepos %s: %v", pkg, err)
		}

		// record the result
		err = b.recordResult(err == nil, pkg, hash, goHash, buildLog, 0)
		if err != nil {
			log.Printf("buildSubrepos %s: %v", pkg, err)
		}
	}
}

// buildSubrepo fetches the given package, updates it to the specified hash,
// and runs 'go test -short pkg/...'. It returns the build log and any error.
func (b *Builder) buildSubrepo(goRoot, goPath, pkg, hash string) (string, error) {
	goTool := filepath.Join(goRoot, "bin", "go") + exeExt
	env := append(b.envv(), "GOROOT="+goRoot, "GOPATH="+goPath)

	// add $GOROOT/bin and $GOPATH/bin to PATH
	for i, e := range env {
		const p = "PATH="
		if !strings.HasPrefix(e, p) {
			continue
		}
		sep := string(os.PathListSeparator)
		env[i] = p + filepath.Join(goRoot, "bin") + sep + filepath.Join(goPath, "bin") + sep + e[len(p):]
	}

	// HACK: check out to new sub-repo location instead of old location.
	pkg = strings.Replace(pkg, "code.google.com/p/go.", "golang.org/x/", 1)

	// fetch package and dependencies
	var outbuf bytes.Buffer
	err := run(exec.Command(goTool, "get", "-d", pkg+"/..."), runEnv(env), allOutput(&outbuf), runDir(goPath))
	if err != nil {
		return outbuf.String(), err
	}
	outbuf.Reset()

	// hg update to the specified hash
	pkgmaster, err := vcs.RepoRootForImportPath(pkg, *verbose)
	if err != nil {
		return "", fmt.Errorf("Error finding subrepo (%s): %s", pkg, err)
	}
	repo := &Repo{
		Path:   filepath.Join(goPath, "src", pkg),
		Master: pkgmaster,
	}
	if err := repo.UpdateTo(hash); err != nil {
		return "", err
	}

	// test the package
	err = run(exec.Command(goTool, "test", "-short", pkg+"/..."),
		runTimeout(*buildTimeout), runEnv(env), allOutput(&outbuf), runDir(goPath))
	return outbuf.String(), err
}

// repoForTool returns the correct RepoRoot for the buildTool, or an error if
// the tool is unknown.
func repoForTool() (*vcs.RepoRoot, error) {
	switch *buildTool {
	case "go":
		return vcs.RepoRootForImportPath(*gcPath, *verbose)
	case "gccgo":
		return vcs.RepoRootForImportPath(gofrontendImportPath, *verbose)
	default:
		return nil, fmt.Errorf("unknown build tool: %s", *buildTool)
	}
}

func isDirectory(name string) bool {
	s, err := os.Stat(name)
	return err == nil && s.IsDir()
}

func isFile(name string) bool {
	s, err := os.Stat(name)
	return err == nil && !s.IsDir()
}

// defaultSuffix returns file extension used for command files in
// current os environment.
func defaultSuffix() string {
	switch runtime.GOOS {
	case "windows":
		return ".bat"
	case "plan9":
		return ".rc"
	default:
		return ".bash"
	}
}

func defaultExeExt() string {
	switch runtime.GOOS {
	case "windows":
		return ".exe"
	default:
		return ""
	}
}

// defaultBuildRoot returns default buildroot directory.
func defaultBuildRoot() string {
	var d string
	if runtime.GOOS == "windows" {
		// will use c:\, otherwise absolute paths become too long
		// during builder run, see http://golang.org/issue/3358.
		d = `c:\`
	} else {
		d = os.TempDir()
	}
	return filepath.Join(d, "gobuilder")
}

// removePath is a more robust version of os.RemoveAll.
// On windows, if remove fails (which can happen if test/benchmark timeouts
// and keeps some files open) it tries to rename the dir.
func removePath(path string) error {
	// Windows will not remove files that are marked read-only.
	// Git has several files which are marked read-only
	// that prevent the path from being removed.
	if runtime.GOOS == "windows" {
		filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
			if info.IsDir() {
				return nil
			}
			if info.Mode() == 0444 {
				os.Chmod(path, 0666)
			}
			return nil
		})
	}
	if err := os.RemoveAll(path); err != nil {
		if runtime.GOOS == "windows" {
			err = os.Rename(path, filepath.Clean(path)+"_remove_me")
		}
		return err
	}
	return nil
}
