// Copyright 2017 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.
//
// This script updates //third_party/boringssl/src to point to the current revision at:
//   https://boringssl.googlesource.com/boringssl/+/master
//
// It also updates the generated build files, Rust bindings, and subset of code used in Zircon.

package main

import (
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"flag"
	"io"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

var (
	boring  = flag.String("boring", "third_party/boringssl", "Path to repository")
	commit  = flag.String("commit", "origin/upstream/master", "Upstream commit-ish to check out")
	fuchsia = flag.String("fuchsia", os.Getenv("FUCHSIA_DIR"), "Fuchsia root directory")
	garnet  = flag.String("garnet", "garnet/manifest", "Path to Garnet manifest directoy")
	zircon  = flag.String("zircon", "zircon/third_party/ulib/uboringssl", "Path to Zircon library")

	skipBoring = flag.Bool("skip-boring", false, "Don't update upstream sources or build files")
	skipRust   = flag.Bool("skip-rust", false, "Don't update Rust bindings")
	skipZircon = flag.Bool("skip-zircon", false, "Don't update Zircon's uboringssl library")
)

// These uboringssl files don't needed to be rolled from BoringSSL.
var skipped_files = map[string]bool{
	"/BUILD.gn":          true,
	"/README.fuchsia.md": true,
	"/rules.mk":          true,
	"/stack-note.S":      true,
}

// Utility functions

func infof(msg string) {
	log.Printf("[+] %s\n", msg)
}

func warnf(msg string) {
	log.Printf("<!> %s\n", msg)
}

// Executes a command with the given |name| and |args| using |cwd| as the current working directory.
func run(cwd string, name string, args ...string) []byte {
	cmd := exec.Command(name, args...)
	if len(cwd) > 0 {
		cmd.Dir = cwd
	}
	out, err := cmd.CombinedOutput()
	if err != nil {
		cmdline := strings.Join(append([]string{name}, args...), " ")
		warnf("Error returned for '" + cmdline + "'")
		warnf("Output: " + string(out))
		log.Fatal(err)
	}
	return out
}

// Sha256Sum returns the hex-encoded SHA256 digest of a file
func sha256sum(path string) string {
	file, err := os.Open(path)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	digest := sha256.New()
	if _, err := io.Copy(digest, file); err != nil {
		log.Fatal(err)
	}
	return hex.EncodeToString(digest.Sum(nil))
}

// Both the Zircon and third-party copies of BoringSSL have a README file that ends with the current
// upstream git revision.  This function updates those files.
func updateReadMe(readmePath string) {
	infof("  Updating README file...")

	// Get the git revision
	rev := run(filepath.Join(*boring, "src"), "git", "rev-list", "HEAD", "--max-count=1")
	revlen := int64(len(rev))
	rev[revlen-1] = '/'

	// Open the README.fuchsia file
	readme, err := os.OpenFile(readmePath, os.O_RDWR, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer readme.Close()

	// Check that the file ends with a git URL
	const urlbase string = "https://fuchsia.googlesource.com/third_party/boringssl/+/"
	urllen := int64(len(urlbase))
	url := make([]byte, urllen)
	off := int64(0)
	var bytes_read int
	info, err := readme.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if info.Size() > urllen+revlen {
		off = info.Size() - (urllen + revlen + 1)
	}
	if bytes_read, err = readme.ReadAt(url, off); err != nil {
		log.Fatal(err)
	}
	if int64(bytes_read) < urllen || urlbase != string(url) {
		log.Fatal(readmePath + " does not end with a valid git URL.")
	}

	// Write the new git revision into the URL
	if _, err = readme.Write(rev); err != nil {
		log.Fatal(err)
	}
}

// Pulls latest BoringSSL for upstream, and generates new build files
func updateBoring() {
	src := filepath.Join(*boring, "src")

	infof("Updating sources...")
	run(src, "git", "fetch")
	run(src, "git", "checkout", *commit)

	updateReadMe(filepath.Join(*boring, "README.fuchsia"))

	infof("Generating build files...")
	run(*boring, "python", filepath.Join(src, "util", "generate_build_files.py"), "gn")
}

// Regenerates the Rust bindings
func updateRust() {
	run("", filepath.Join(*boring, "rust/boringssl-sys/bindgen.sh"))
}

// To update Zircon's uboringssl library, we update the revision number in the README file and
// copy any files present in uboringssl that do not match their counterpart in BoringSSL
func updateZircon() {
	updateReadMe(filepath.Join(*zircon, "README.fuchsia.md"))

	infof("  Updating sources from BoringSSL...")
	missing_files := map[string]bool{}
	walker := func(zirconPath string, zxInfo os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if zxInfo.IsDir() {
			return nil
		}
		stem := zirconPath[len(*zircon):]
		if skipped_files[stem] {
			return nil
		}
		// Look for the matching file under boringssl or boringssl/src
		boringPath := filepath.Join(*boring, stem)
		if _, err = os.Stat(boringPath); os.IsNotExist(err) {
			boringPath = filepath.Join(*boring, "src", stem)
		}
		if _, err = os.Stat(boringPath); os.IsNotExist(err) {
			missing_files[stem] = true
		}
		// Copy files that have changed
		if sha256sum(boringPath) != sha256sum(zirconPath) {
			run(*fuchsia, "cp", boringPath, zirconPath)
		}
		return nil
	}
	if err := filepath.Walk(*zircon, walker); err != nil {
		log.Fatal(err)
	}
	// Warn about missing files
	if len(missing_files) != 0 {
		warnf("ERROR: These files are missing from upstream:")
		for file := range missing_files {
			warnf(file)
		}
		log.Fatal("Please resolve these files and try again.")
	}
}

// Main function
func main() {
	flag.Parse()
	if len(*fuchsia) == 0 {
		log.Fatal(errors.New("FUCHSIA_DIR not set and --fuchsia not specified"))
	}
	*boring = filepath.Join(*fuchsia, *boring)
	*zircon = filepath.Join(*fuchsia, *zircon)

	if !*skipBoring {
		infof("Updating BoringSSL from upstream...")
		updateBoring()
		infof("Done!")
		infof("")
		infof("To test, please run:")
		infof("  $ fx set ... --preinstall garnet/packages/tests/boringssl")
		infof("  $ fx build")
		infof("  $ fx serve")
		infof("  $ fx run-test boringssl_tests")
		infof("If tests pass; commit the changes in " + *boring)
		infof("Then, update the BoringSSL revisions in the internal integration repository.")
	}

	if !*skipRust {
		infof("Updating Rust bindings...")
		updateRust()
		infof("Done!")
	}

	if !*skipZircon {
		infof("Updating Zircon's uboringssl library...")
		updateZircon()
		infof("Done!")
		infof("")
		infof("To test, please run launch Zircon and run:")
		infof("  > k ut prng")
		infof("  > /boot/test/sys/crypto_test")
		infof("If tests pass; commit the changes in " + *zircon)
	}

	infof("Finally, update the BoringSSL revisions in the internal integration repository.")
	infof("You can use `" + *boring + "/check-integration`to verify the revisions.")
}
