// 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 gitlock command helps write Dockerfiles with a bunch of lines
// to lock git dependencies in place.
package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"go/build"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strings"
)

var (
	ignorePrefixFlag = flag.String("ignore", "golang.org/x/build", "comma-separated list of package prefixes to ignore")
	updateFile       = flag.String("update", "", "if non-empty, the Dockerfile to update. must have \"# BEGIN deps\" and \"# END deps\" lines.")
)

var ignorePrefixes []string

func parseDockerFile() (header, footer []byte) {
	if *updateFile == "" {
		return nil, nil
	}
	var headBuf, footBuf bytes.Buffer
	slurp, err := ioutil.ReadFile(*updateFile)
	if err != nil {
		log.Fatal(err)
	}
	var sawBegin, sawEnd bool
	bs := bufio.NewScanner(bytes.NewReader(slurp))
	for bs.Scan() {
		if !sawBegin {
			headBuf.Write(bs.Bytes())
			headBuf.WriteByte('\n')
			if strings.HasPrefix(bs.Text(), "# BEGIN deps") {
				sawBegin = true
				continue
			}
			continue
		}
		if strings.HasPrefix(bs.Text(), "# END deps") {
			sawEnd = true
		}
		if sawEnd {
			footBuf.Write(bs.Bytes())
			footBuf.WriteByte('\n')
		}
	}
	if err := bs.Err(); err != nil {
		log.Fatalf("error parsing %s: %v", *updateFile, err)
	}
	if !sawBegin {
		log.Fatalf(`file %s is missing a "# BEGIN deps" line`, *updateFile)
	}
	if !sawEnd {
		log.Fatalf(`file %s is missing a "# END deps" line`, *updateFile)
	}
	return headBuf.Bytes(), footBuf.Bytes()
}

func main() {
	flag.Parse()
	ignorePrefixes = strings.Split(*ignorePrefixFlag, ",")
	if flag.NArg() != 1 {
		log.SetFlags(0)
		log.Fatalf("Usage: gitlock <package>")
	}
	mainPkg := flag.Arg(0) // not necessary "package main", but almost certainly.
	header, footer := parseDockerFile()

	depOut, err := exec.Command("go", "list", "-f", "{{range .Deps}}{{.}}\n{{end}}", mainPkg).Output()
	if err != nil {
		log.Fatalf("listing deps of %q: %v", mainPkg, formatExecErr(err))
	}

	var deps []string
	for _, pkg := range strings.Split(string(depOut), "\n") {
		if ignorePkg(pkg) {
			continue
		}
		deps = append(deps, pkg)
	}
	sort.Strings(deps)

	// Build a map of root git dir => packages using that root git dir.
	var gitDirPkgs = map[string][]string{}
	for _, pkg := range deps {
		buildPkg, err := build.Import(pkg, "", build.FindOnly)
		if err != nil {
			log.Fatalf("importing %s: %v", pkg, err)
		}
		pkgDir := buildPkg.Dir
		gitDir, err := findGitDir(pkgDir)
		if err != nil {
			log.Fatalf("finding git dir of %s: %v", pkgDir, err)
		}
		gitDirPkgs[gitDir] = append(gitDirPkgs[gitDir], pkg)
	}

	// Sorted list of unique git root dirs.
	var gitDirs []string
	for d := range gitDirPkgs {
		gitDirs = append(gitDirs, d)
	}
	sort.Strings(gitDirs)

	var buf bytes.Buffer
	var out io.Writer = os.Stdout
	if *updateFile != "" {
		buf.Write(header)
		buf.WriteByte('\n')
		out = &buf
	}
	for _, gitDir := range gitDirs {
		cmd := exec.Command("git", "log", "-n", "1", "--pretty=%H %ci")
		cmd.Dir = gitDir
		stdout, err := cmd.Output()
		if err != nil {
			log.Fatal(err)
		}
		f := strings.SplitN(strings.TrimSpace(string(stdout)), " ", 2)
		hash, ymd := f[0], f[1][:10]

		repoName := gitDir[strings.Index(gitDir, "/src/")+5:]

		var comment string
		if n := len(gitDirPkgs[gitDir]); n > 1 {
			comment = fmt.Sprintf(" `#and %d other pkgs`", n)
		}
		fmt.Fprintf(out, "# Repo %s at %s (%s)\n", repoName, hash[:7], ymd)
		fmt.Fprintf(out, "ENV REV=%s\n", hash)
		fmt.Fprintf(out, "RUN go get -d %s%s &&\\\n", gitDirPkgs[gitDir][0], comment)
		fmt.Fprintf(out, "    (cd /go/src/%s && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)\n\n", repoName)
	}

	fmt.Fprintf(out, "# Optimization to speed up iterative development, not necessary for correctness:\n")
	fmt.Fprintf(out, "RUN go install %s\n", strings.Join(deps, " \\\n\t"))

	if *updateFile == "" {
		return
	}
	buf.Write(footer)
	if err := ioutil.WriteFile(*updateFile, buf.Bytes(), 0644); err != nil {
		log.Fatal(err)
	}
}

func findGitDir(dir string) (string, error) {
	dir0 := dir
	var lastDir string
	for dir != "" && dir != "." && dir != lastDir {
		fi, err := os.Stat(filepath.Join(dir, ".git"))
		if err == nil && fi.IsDir() {
			return dir, nil
		}
		if err != nil && !os.IsNotExist(err) {
			return "", err
		}
		lastDir = dir
		dir = filepath.Dir(dir)
	}
	return "", fmt.Errorf("no git dir found for %s", dir0)
}

// ignorePkg reports whether pkg, if it appears as a dependency of the
// root package, should be omitted from the output.
func ignorePkg(pkg string) bool {
	if strings.HasPrefix(pkg, "vendor/") || !strings.Contains(pkg, ".") {
		return true
	}
	for _, pfx := range ignorePrefixes {
		if strings.HasPrefix(pkg, pfx) {
			return true
		}
	}
	return false
}

func formatExecErr(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)
}
