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

// The go-contrib-init command helps new Go contributors get their development
// environment set up for the Go contribution process.
//
// It aims to be a complement or alternative to https://golang.org/doc/contribute.html.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
)

var (
	repo = flag.String("repo", detectrepo(), "Which go repo you want to contribute to. Use \"go\" for the core, or e.g. \"net\" for golang.org/x/net/*")
	dry  = flag.Bool("dry-run", false, "Fail with problems instead of trying to fix things.")
)

func main() {
	log.SetFlags(0)
	flag.Parse()

	checkCLA()
	checkGoroot()
	checkWorkingDir()
	checkGitOrigin()
	checkGitCodeReview()
	fmt.Print("All good. Happy hacking!\n" +
		"Remember to squash your revised commits and preserve the magic Change-Id lines.\n" +
		"Next steps: https://golang.org/doc/contribute.html#commit_changes\n")
}

func detectrepo() string {
	wd, err := os.Getwd()
	if err != nil {
		return "go"
	}

	for _, path := range filepath.SplitList(os.Getenv("GOPATH")) {
		rightdir := filepath.Join(path, "src", "golang.org", "x")
		if strings.HasPrefix(wd, rightdir) {
			tail := wd[len(rightdir)+1:]
			end := strings.Index(tail, string(os.PathSeparator))
			if end > 0 {
				repo := tail[:end]
				return repo
			}
		}
	}

	return "go"
}

func checkCLA() {
	slurp, err := ioutil.ReadFile(cookiesFile())
	if err != nil && !os.IsNotExist(err) {
		log.Fatal(err)
	}
	if bytes.Contains(slurp, []byte("go.googlesource.com")) &&
		bytes.Contains(slurp, []byte("go-review.googlesource.com")) {
		// Probably good.
		return
	}
	log.Fatal("Your .gitcookies file isn't configured.\n" +
		"Next steps:\n" +
		"  * Submit a CLA (https://golang.org/doc/contribute.html#cla) if not done\n" +
		"  * Go to https://go.googlesource.com/ and click \"Generate Password\" at the top,\n" +
		"    then follow instructions.\n" +
		"  * Run go-contrib-init again.\n")
}

func cookiesFile() string {
	if runtime.GOOS == "windows" {
		return filepath.Join(os.Getenv("USERPROFILE"), ".gitcookies")
	}
	return filepath.Join(os.Getenv("HOME"), ".gitcookies")
}

func checkGoroot() {
	v := os.Getenv("GOROOT")
	if v == "" {
		return
	}
	if *repo == "go" {
		if strings.HasPrefix(v, "/usr/") {
			log.Fatalf("Your GOROOT environment variable is set to %q\n"+
				"This is almost certainly not what you want. Either unset\n"+
				"your GOROOT or set it to the path of your development version\n"+
				"of Go.", v)
		}
		slurp, err := ioutil.ReadFile(filepath.Join(v, "VERSION"))
		if err == nil {
			slurp = bytes.TrimSpace(slurp)
			log.Fatalf("Your GOROOT environment variable is set to %q\n"+
				"But that path is to a binary release of Go, with VERSION file %q.\n"+
				"You should hack on Go in a fresh checkout of Go. Fix or unset your GOROOT.\n",
				v, slurp)
		}
	}
}

func checkWorkingDir() {
	if *repo == "go" {
		if inGoPath() {
			log.Fatal("You can't work on Go from within your GOPATH. Please checkout Go outside of your GOPATH")
		}
		return
	}
	wd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}

	gopath := firstGoPath()
	if gopath == "" {
		log.Fatal("Your GOPATH is not set, please set it")
	}

	rightdir := filepath.Join(gopath, "src", "golang.org", "x", *repo)
	if !strings.HasPrefix(wd, rightdir) {
		dirExists, err := exists(rightdir)
		if err != nil {
			log.Fatal(err)
		}
		if !dirExists {
			log.Fatalf("The repo you want to work on is currently not on your system.\n"+
				"Run %q to obtain this repo\n"+
				"then go to the directory %q\n",
				"go get -d golang.org/x/"+*repo, rightdir)
		}
		log.Fatalf("Your current directory is:%q\n"+
			"Working on golang/x/%v requires you be in %q\n",
			wd, *repo, rightdir)
	}
}

func firstGoPath() string {
	list := filepath.SplitList(os.Getenv("GOPATH"))
	if len(list) < 1 {
		return ""
	}
	return list[0]
}

func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if os.IsNotExist(err) {
		return false, nil
	}
	return true, err
}

func inGoPath() bool {
	wd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}

	if os.Getenv("GOPATH") == "" {
		return false
	}

	for _, path := range filepath.SplitList(os.Getenv("GOPATH")) {
		if strings.HasPrefix(wd, filepath.Join(path, "src")) {
			return true
		}
	}

	return false
}

// mostly check that they didn't clone from github
func checkGitOrigin() {
	if _, err := exec.LookPath("git"); err != nil {
		log.Fatalf("You don't appear to have git installed. Do that.")
	}
	wantRemote := "https://go.googlesource.com/" + *repo
	remotes, err := exec.Command("git", "remote", "-v").Output()
	if err != nil {
		msg := cmdErr(err)
		if strings.Contains(msg, "Not a git repository") {
			log.Fatalf("Your current directory is not in a git checkout of %s", wantRemote)
		}
		log.Fatalf("Error running git remote -v: %v", msg)
	}
	matches := 0
	for _, line := range strings.Split(string(remotes), "\n") {
		line = strings.TrimSpace(line)
		if !strings.HasPrefix(line, "origin") {
			continue
		}
		if !strings.Contains(line, wantRemote) {
			curRemote := strings.Fields(strings.TrimPrefix(line, "origin"))[0]
			// TODO: if not in dryRun mode, just fix it?
			log.Fatalf("Current directory's git was cloned from %q; origin should be %q", curRemote, wantRemote)
		}
		matches++
	}
	if matches == 0 {
		log.Fatalf("git remote -v output didn't contain expected %q. Got:\n%s", wantRemote, remotes)
	}
}

func cmdErr(err error) string {
	if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 {
		return fmt.Sprintf("%s: %s", err, ee.Stderr)
	}
	return fmt.Sprint(err)
}

func checkGitCodeReview() {
	if _, err := exec.LookPath("git-codereview"); err != nil {
		if *dry {
			log.Fatalf("You don't appear to have git-codereview tool. While this is technically optional,\n" +
				"almost all Go contributors use it. Our documentation and this tool assume it is used.\n" +
				"To install it, run:\n\n\t$ go get golang.org/x/review/git-codereview\n\n(Then run go-contrib-init again)")
		}
		err := exec.Command("go", "get", "golang.org/x/review/git-codereview").Run()
		if err != nil {
			log.Printf("Error running go get golang.org/x/review/git-codereview: %v", cmdErr(err))
		}
		log.Printf("Installed git-codereview (ran `go get golang.org/x/review/git-codereview`)")
	}
	missing := false
	for _, cmd := range []string{"change", "gofmt", "mail", "pending", "submit", "sync"} {
		v, _ := exec.Command("git", "config", "alias."+cmd).Output()
		if strings.Contains(string(v), "codereview") {
			continue
		}
		if *dry {
			log.Printf("Missing alias. Run:\n\t$ git config alias.%s \"codereview %s\"", cmd, cmd)
			missing = true
		} else {
			err := exec.Command("git", "config", "alias."+cmd, "codereview "+cmd).Run()
			if err != nil {
				log.Fatalf("Error setting alias.%s: %v", cmd, cmdErr(err))
			}
		}
	}
	if missing {
		log.Fatalf("Missing aliases. (While optional, this tool assumes you use them.)")
	}
}
