// Copyright 2018 The Fuchsia 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 makeroot.go script copies a GOROOT. It is a precursor to makefuchsia.go,
// used to stage a clean GOROOT into the build directory.
// Note: this script exists because the `go` tool globs for inputs, as such, a
// copy tool is required that will actively remove files that are not found in
// the source.

package main

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

var (
	sourceGoroot = flag.String("source-goroot", "", "GOROOT to copy from")
	targetGoroot = flag.String("target-goroot", "", "GOROOT to copy into")
	depfilePath  = flag.String("depfile", "", "depfile to write into")
	depfileRoot  = flag.String("depfile-root", "", "Path from which dependency paths should be rooted")
	stampPath    = flag.String("stamp-file", "", "Path of a file to create upon completion")
)

func mkdir(path ...string) {
	if err := os.MkdirAll(join(path...), 0755); err != nil {
		log.Fatal(err)
	}
}

func join(path ...string) string { return filepath.Join(path...) }

func copyfile(src, dst string) {
	srcfile, err := os.Open(src)
	if err != nil {
		log.Fatal(err)
	}
	defer srcfile.Close()

	fi, err := srcfile.Stat()
	if err != nil {
		log.Fatal(err)
	}

	mkdir(filepath.Dir(dst))
	f, err := os.OpenFile(dst, os.O_CREATE|os.O_RDWR|os.O_TRUNC, fi.Mode())
	if err != nil {
		log.Fatal(err)
	}
	if _, err := io.Copy(f, srcfile); err != nil {
		log.Fatalf("cp %s %s: %v", src, dst, err)
	}
	if err := f.Close(); err != nil {
		log.Fatalf("cp %s %s: close: %v", src, dst, err)
	}
}

// allFilesIn recursively walks a set of files, returning the entire tree in
// paths relative to the given root. A map is returned for convenience. If
// prefix is given, only files that match the prefix are considered.
func allFilesIn(root string, paths map[string]struct{}, prefix ...string) error {
	return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil || info.IsDir() {
			return err
		}
		for _, pfx := range prefix {
			if strings.HasPrefix(path, join(root, pfx)) {
				relPath := strings.TrimPrefix(path, root)[1:]
				paths[relPath] = struct{}{}
				return err
			}
		}
		return err
	})
}

func main() {
	log.SetFlags(0)
	log.SetPrefix("makeroot.go: ")
	flag.Parse()

	srcFiles := map[string]struct{}{}

	// The list of files included below should include everything that Go itself
	// cares about. It used to avoid containing some of the "extraneous" files such
	// as doc/ and test/, however, eliding those files results in `go doc -http`
	// not presenting well for the user, so it's simply better to include
	// everything.
	err := allFilesIn(join(*sourceGoroot), srcFiles,
		"AUTHORS",
		"CONTRIBUTING.md",
		"CONTRIBUTORS",
		"LICENSE",
		"PATENTS",
		"README.md",
		"VERSION",
		"makefuchsia.go",
		"api/",
		"doc/",
		"favicon.ico",
		"lib/",
		"misc/",
		"robots.txt",
		"src/",
		"test/",
	)
	if err != nil {
		log.Fatal(err)
	}

	dstFiles := map[string]struct{}{}
	if _, err := os.Stat(join(*targetGoroot)); err == nil {
		if err := allFilesIn(join(*targetGoroot), dstFiles, ""); err != nil {
			log.Fatal(err)
		}
	}

	for f := range dstFiles {
		if _, ok := srcFiles[f]; !ok {
			// try to preserve the bin/ and pkg/ trees, as they can be used to do faster
			// rebuilds of the toolchain.
			if strings.HasPrefix(f, "src/") || strings.HasPrefix(f, "misc/fuchsia/") {
				os.Remove(filepath.Join(*targetGoroot, f))
			}
		}
	}

	buf := bytes.NewBuffer(nil)
	fmt.Fprintf(buf, "%s:", *stampPath)
	for f := range srcFiles {
		src, dst := join(*sourceGoroot, f), join(*targetGoroot, f)
		copyfile(src, dst)
		fmt.Fprintf(buf, " %s", src)
	}
	fmt.Fprintf(buf, "\n")

	if err := ioutil.WriteFile(*depfilePath, buf.Bytes(), os.ModePerm); err != nil {
		log.Fatal(err)
	}

	if err := ioutil.WriteFile(*stampPath, []byte(fmt.Sprintf("%s", time.Now())), os.ModePerm); err != nil {
		log.Fatal(err)
	}
}
