// Copyright 2016 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 genbootstrap command prepares GO_BOOTSTRAP tarballs suitable for
use on builders. It's a wrapper around bootstrap.bash. After
bootstrap.bash produces the full output, genbootstrap trims it up,
removing unnecessary and unwanted files.

Usage:  genbootstrap GOOS/GOARCH
*/
package main

import (
	"flag"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

var skipBuild = flag.Bool("skip_build", false, "skip bootstrap.bash step; useful during development of cleaning code")

func usage() {
	log.Fatalf("Usage: genbootstrap GOOS/GOARCH")
}

func main() {
	flag.Parse()
	if flag.NArg() != 1 {
		usage()
	}
	f := strings.Split(flag.Arg(0), "/")
	if len(f) != 2 {
		usage()
	}
	goos, goarch := f[0], f[1]
	if os.Getenv("GOROOT") == "" {
		log.Fatalf("GOROOT not set in environment")
	}

	tgz := filepath.Join(os.Getenv("GOROOT"), "src", "..", "..", "gobootstrap-"+goos+"-"+goarch+".tar.gz")
	os.Remove(tgz)
	outDir := filepath.Join(os.Getenv("GOROOT"), "src", "..", "..", "go-"+goos+"-"+goarch+"-bootstrap")
	if !*skipBuild {
		os.RemoveAll(outDir)
		cmd := exec.Command(filepath.Join(os.Getenv("GOROOT"), "src", "bootstrap.bash"))
		cmd.Dir = filepath.Join(os.Getenv("GOROOT"), "src")
		cmd.Env = append(os.Environ(), "GOOS="+goos, "GOARCH="+goarch)
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Run(); err != nil {
			log.Fatal(err)
		}

		// bootstrap.bash makes a bzipped tar file too, but it's fat and full of stuff we
		// dont need it. delete it.
		os.Remove(outDir + ".tbz")
	}

	if err := filepath.Walk(outDir, func(path string, fi os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		rel := strings.TrimPrefix(strings.TrimPrefix(path, outDir), "/")
		base := filepath.Base(path)
		var pkgrel string // relative to pkg/<goos>_<goarch>/, or empty
		if strings.HasPrefix(rel, "pkg/") && strings.Count(rel, "/") >= 2 {
			pkgrel = strings.TrimPrefix(rel, "pkg/")
			pkgrel = pkgrel[strings.Index(pkgrel, "/")+1:]
			log.Printf("rel %q => %q", rel, pkgrel)
		}
		remove := func() error {
			if err := os.RemoveAll(path); err != nil {
				return err
			}
			if fi.IsDir() {
				return filepath.SkipDir
			}
			return nil
		}
		switch pkgrel {
		case "cmd",
			"database", "database.a",
			"image", "image.a",
			"net.a",
			"net",
			"runtime/cgo.a",
			"vendor/golang.org/x/net":
			return remove()
		}
		switch rel {
		case "api",
			"bin/gofmt",
			"doc",
			"misc/android",
			"misc/cgo",
			"misc/chrome",
			"misc/swig",
			"src/cmd",
			"src/net",
			"src/runtime/cgo",
			"src/database",
			"src/image",
			"src/vendor/golang.org/x/net",
			"test":
			return remove()
		}
		if base == "testdata" {
			return remove()
		}
		if strings.HasPrefix(rel, "pkg/tool/") {
			switch base {
			case "addr2line", "api", "cgo", "cover",
				"dist", "doc", "fix", "nm",
				"objdump", "pack", "pprof",
				"trace", "vet", "yacc":
				return remove()
			}
		}
		if fi.IsDir() {
			return nil
		}
		if isEditorJunkFile(path) {
			return remove()
		}
		if !fi.Mode().IsRegular() {
			return remove()
		}
		if strings.HasSuffix(path, "_test.go") {
			return remove()
		}
		log.Printf("keeping: %s\n", rel)
		return nil
	}); err != nil {
		log.Fatal(err)
	}

	log.Printf("Running: tar zcf %s .", tgz)
	cmd := exec.Command("tar", "zcf", tgz, ".")
	cmd.Dir = outDir
	if err := cmd.Run(); err != nil {
		log.Fatalf("tar zf failed: %v", err)
	}
	log.Printf("Done. Output is %s", tgz)
}

func isEditorJunkFile(path string) bool {
	path = filepath.Base(path)
	if strings.HasPrefix(path, "#") && strings.HasSuffix(path, "#") {
		return true
	}
	if strings.HasSuffix(path, "~") {
		return true
	}
	return false
}
