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

package cipd

import (
	"bufio"
	"bytes"
	"context"
	"crypto/sha256"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"time"

	"go.fuchsia.dev/jiri"
	"go.fuchsia.dev/jiri/cmdline"
	"go.fuchsia.dev/jiri/log"
	"go.fuchsia.dev/jiri/retry"
	"go.fuchsia.dev/jiri/version"
	"golang.org/x/sync/semaphore"
)

const (
	cipdBackend = "https://chrome-infra-packages.appspot.com"
	// This git hash corresponds to a commit in https://chromium.googlesource.com/infra/infra
	// to update the pinned version of the CIPD client in the DEPS file.
	cipdVersion       = "git_revision:61ac72e84956112656e2500701dd252c5d92f6e6"
	cipdVersionDigest = `
# This file was generated by
#
#  cipd selfupdate-roll -version-file cipd_version \
#      -version git_revision:61ac72e84956112656e2500701dd252c5d92f6e6
#
# Do not modify manually. All changes will be overwritten.
# Use 'cipd selfupdate-roll ...' to modify.

aix-ppc64       sha256  82666df4584edad4098ce0b3683bd744f8d6b66a18513dae2606b63366dc0fb1
linux-386       sha256  5f96fd7b73bd927b07f37ddb04e393ca0ed71b5f9adb94a8e4bf2ff05a17d1a8
linux-amd64     sha256  9c532dd340d507e396699e9b29d801d17943ca5b9ea3ba4f5c9e752b2e9d9376
linux-arm64     sha256  e45e3d5d81edc32b16bccb0e7d403bc4f79ecc14c2fb12e0ade7e3b84fbd4793
linux-armv6l    sha256  678f9c99a4e828def0804f8cfeca6cf9f0f59889fb3337f30ceb7f7e17517a3e
linux-mips64    sha256  9f9712821b69f5d11d85189a0b3950ccb6a3388be65fa40477ee8be79e3a14b9
linux-mips64le  sha256  eccb2d3438c7e8b649788ead64e2faa00d56a9494561e4f621fccc1335a74104
linux-mipsle    sha256  6f05945d9b0eb9d14550b1e836ebbe5b57e0f79e8f3a548775766f5a96ae6164
linux-ppc64     sha256  f0fdcf91585468bad83e2430a4fc8438696edd21c26d9a05076068129e995a34
linux-ppc64le   sha256  30a917b27af8e80d17f83d3575cf655d451bf02cc974e9fff1aba4310ecd1efa
linux-s390x     sha256  75cb9789102896416436fc033b25f9089c72ae1ae7631bf0a9785c589a467e79
mac-amd64       sha256  906efd93e265a169b4262b9c88bd9fd18440128d8f949acc0c429b6c0d6f3b76
windows-386     sha256  3f45aa6d5e9e002b4df97276688c4e71e5e437823835c6e047340c31bdedb43c
windows-amd64   sha256  a58d48748344c45a9511aab5b9b78d78fd6234c83ec9417700d81d2db8e5050d
`
	exitCodeNoValidToken   = 1
	cipdManifestInvalidErr = cmdline.ErrExitCode(25)
)

var (
	// CipdPlatform represents the current runtime platform in cipd platform notation.
	CipdPlatform   Platform
	cipdOS         string
	cipdArch       string
	cipdBinary     string
	selfUpdateOnce sync.Once
	templateRE     = regexp.MustCompile(`\${[^}]*}`)

	// ErrSkipTemplate may be returned from Expander.Expand to indicate that
	// a given expansion doesn't apply to the current template parameters. For
	// example, expanding `"foo/${os=linux,mac}"` with a template parameter of "os"
	// == "win", would return ErrSkipTemplate.
	ErrSkipTemplate = errors.New("package template does not apply to the current system")
)

func init() {
	cipdOS = runtime.GOOS
	cipdArch = runtime.GOARCH
	if cipdOS == "darwin" {
		cipdOS = "mac"
	}
	if cipdArch == "arm" {
		cipdArch = "armv6l"
	}
	CipdPlatform = Platform{cipdOS, cipdArch}
}

func fetchBinary(jirix *jiri.X, binaryPath, platform, version, digest string) error {
	cipdURL := fmt.Sprintf("%s/client?platform=%s&version=%s", cipdBackend, platform, version)
	data, err := fetchFile(jirix, cipdURL)
	if err != nil {
		return err
	}
	if verified, err := verifyDigest(data, digest); err != nil || !verified {
		if err != nil {
			return err
		}
		return errors.New("cipd failed integrity test")
	}
	// cipd binary verified. Save to disk
	if _, err := os.Stat(filepath.Dir(binaryPath)); os.IsNotExist(err) {
		if err := os.MkdirAll(filepath.Dir(binaryPath), 0755); err != nil {
			return fmt.Errorf("failed to create parent directory %q for cipd: %v", filepath.Dir(binaryPath), err)
		}
	}
	return writeFile(binaryPath, data)
}

// Bootstrap returns the path of a valid cipd binary. It will fetch cipd from
// remote if a valid cipd binary is not found. It will update cipd if there
// is a new version.
func Bootstrap(jirix *jiri.X, binaryPath string) (string, error) {
	cipdBinary = binaryPath
	bootstrap := func() error {
		// Fetch cipd digest
		cipdDigest, _, err := fetchDigest(CipdPlatform.String())
		if err != nil {
			return err
		}
		if cipdBinary == "" {
			return errors.New("cipd binary path was not set")
		}
		if err != nil {
			return err
		}
		return fetchBinary(jirix, cipdBinary, CipdPlatform.String(), cipdVersion, cipdDigest)
	}

	getCipd := func() (string, error) {
		if cipdBinary == "" {
			return "", errors.New("cipd binary path was not set")
		}
		fileInfo, err := os.Stat(cipdBinary)
		if err != nil {
			if os.IsNotExist(err) {
				return "", fmt.Errorf("cipd binary was not found at %q", cipdBinary)
			}
			return "", err
		}
		// Check if cipd binary has execution permission
		if fileInfo.Mode()&0111 == 0 {
			return "", fmt.Errorf("cipd binary at %q is not executable", cipdBinary)
		}
		return cipdBinary, nil
	}

	cipdPath, err := getCipd()
	if err != nil {
		// Could not find cipd binary or cipd is invalid
		// Bootstrap it from scratch
		if err := bootstrap(); err != nil {
			return "", err
		}
		return cipdBinary, nil
	}
	// cipd is found, do self update
	var e error
	selfUpdateOnce.Do(func() {
		e = selfUpdate(cipdPath, cipdVersion)
	})
	if e != nil {
		// Self update is unsuccessful, redo bootstrap
		if err := bootstrap(); err != nil {
			return "", err
		}
	}
	return cipdPath, nil
}

// FuchsiaPlatform returns a Platform struct which can be used in
// determing the correct path for prebuilt packages. It replace
// the os and arch names from cipd format to a format used by
// Fuchsia developers.
func FuchsiaPlatform(plat Platform) Platform {
	retPlat := Platform{
		OS:   plat.OS,
		Arch: plat.Arch,
	}
	// Currently cipd use "amd64" for x86_64 while fuchsia use "x64",
	// replace "amd64" with "x64".
	// There might be other differences that need to be addressed in
	// the future.
	switch retPlat.Arch {
	case "amd64":
		retPlat.Arch = "x64"
	}
	return retPlat
}

func fetchDigest(platform string) (digest, method string, err error) {
	var digestBuf bytes.Buffer
	digestBuf.Write([]byte(cipdVersionDigest))
	digestScanner := bufio.NewScanner(&digestBuf)
	for digestScanner.Scan() {
		curLine := digestScanner.Text()
		if len(curLine) == 0 || curLine[0] == '#' {
			// Skip comment or empty line
			continue
		}
		fields := strings.Fields(curLine)
		if len(fields) != 3 {
			return "", "", errors.New("unsupported cipd digest file format")
		}
		if fields[0] == platform {
			digest = fields[2]
			method = fields[1]
			err = nil
			return
		}
	}
	return "", "", errors.New("no matching platform found in cipd digest file")
}

func selfUpdate(cipdPath, cipdVersion string) error {
	args := []string{"selfupdate", "-version", cipdVersion, "-service-url", cipdBackend}
	command := exec.Command(cipdPath, args...)
	return command.Run()
}

func writeFile(filePath string, data []byte) error {
	tempFile, err := ioutil.TempFile(path.Dir(filePath), "cipd.*")
	if err != nil {
		return err
	}
	defer tempFile.Close()
	defer os.Remove(tempFile.Name())
	if _, err := tempFile.Write(data); err != nil {
		// Write errors
		return errors.New("I/O error while downloading cipd binary")
	}
	// Set mode to rwxr-xr-x
	if err := tempFile.Chmod(0755); err != nil {
		// Chmod errors
		return errors.New("I/O error while adding executable permission to cipd binary")
	}
	tempFile.Close()
	if err := os.Rename(tempFile.Name(), filePath); err != nil {
		return err
	}
	return nil
}

func verifyDigest(data []byte, cipdDigest string) (bool, error) {
	hash := sha256.Sum256(data)
	hashString := fmt.Sprintf("%x", hash)
	if hashString == strings.ToLower(cipdDigest) {
		return true, nil
	}
	return false, nil
}

func getUserAgent() string {
	ua := "jiri/" + version.GitCommit
	if version.GitCommit == "" {
		ua += "debug"
	}
	return ua
}

func fetchFile(jirix *jiri.X, url string) ([]byte, error) {
	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Set("User-Agent", getUserAgent())
	var contents []byte
	if err := retry.Function(jirix, func() error {
		resp, err := client.Do(req)
		if err != nil {
			return err
		}
		defer resp.Body.Close()
		if resp.StatusCode >= 400 {
			return fmt.Errorf("got non-success response: %s", resp.Status)
		}
		contents, err = ioutil.ReadAll(resp.Body)
		return err
	}, fmt.Sprintf("bootstrapping cipd binary"), retry.AttemptsOpt(jirix.Attempts)); err != nil {
		jirix.Logger.Errorf("error: failed to download cipd client: %v\n", err)
		return nil, err
	}
	return contents, nil
}

type packageACL struct {
	path   string
	access bool
}

func checkPackageACL(jirix *jiri.X, cipdPath, jsonDir string, c chan<- packageACL) {
	// cipd should be already bootstrapped before this go routine.
	// Silently return a false just in case if cipd is not found.
	if cipdBinary == "" {
		c <- packageACL{path: cipdPath, access: false}
		return
	}

	jsonFile, err := ioutil.TempFile(jsonDir, "cipd*.json")
	if err != nil {
		jirix.Logger.Warningf("Error while creating temporary file for cipd")
		c <- packageACL{path: cipdPath, access: false}
		return
	}
	jsonFileName := jsonFile.Name()
	jsonFile.Close()

	args := []string{"acl-check", "-reader", "-json-output", jsonFileName, cipdPath}
	jirix.Logger.Debugf("Invoke cipd with %v", args)

	command := exec.Command(cipdBinary, args...)
	var stdoutBuf, stderrBuf bytes.Buffer
	command.Stdout = &stdoutBuf
	command.Stderr = &stderrBuf
	// Return false if cipd cannot be executed or output jsonfile contains false.
	if err := command.Run(); err != nil {
		jirix.Logger.Debugf("Error while executing cipd, err: %q, stderr: %q", err, stderrBuf.String())
		c <- packageACL{path: cipdPath, access: false}
		return
	}

	jsonData, err := ioutil.ReadFile(jsonFileName)
	if err != nil {
		c <- packageACL{path: cipdPath, access: false}
		return
	}

	var result struct {
		Result bool `json:"result"`
	}
	if err := json.Unmarshal(jsonData, &result); err != nil {
		c <- packageACL{path: cipdPath, access: false}
		return
	}

	if !result.Result {
		c <- packageACL{path: cipdPath, access: false}
		return
	}

	// Package can be accessed.
	c <- packageACL{path: cipdPath, access: true}
	return
}

// CheckPackageACL checks cipd's access to packages in map "pkgs". The package
// names in "pkgs" should have trailing '/' removed before calling this
// function.
func CheckPackageACL(jirix *jiri.X, pkgs map[string]bool) error {
	// Not declared as CheckPackageACL(jirix *jiri.X, pkgs map[*package.Package]bool)
	// due to import cycles. Package jiri/package imports jiri/cipd so here we cannot
	// import jiri/package.
	if _, err := Bootstrap(jirix, jirix.CIPDPath()); err != nil {
		return err
	}

	jsonDir, err := ioutil.TempDir("", "jiri_cipd")
	if err != nil {
		return err
	}
	defer os.RemoveAll(jsonDir)

	c := make(chan packageACL)
	for key := range pkgs {
		go checkPackageACL(jirix, key, jsonDir, c)
	}

	for i := 0; i < len(pkgs); i++ {
		acl := <-c
		pkgs[acl.path] = acl.access
	}
	return nil
}

// CheckLoggedIn checks cipd's user login information. It will return true
// if login information is found or return false if login information is not
// found.
func CheckLoggedIn(jirix *jiri.X) (bool, error) {
	cipdPath, err := Bootstrap(jirix, jirix.CIPDPath())
	if err != nil {
		return false, err
	}
	args := []string{"auth-info"}
	command := exec.Command(cipdPath, args...)
	var stdoutBuf, stderrBuf bytes.Buffer
	command.Stdout = &stdoutBuf
	command.Stderr = &stderrBuf
	if err := command.Run(); err != nil {
		stdErrMsg := strings.TrimSpace(stderrBuf.String())
		jirix.Logger.Debugf("Error happend while executing cipd, err: %q, stderr: %q", err, stdErrMsg)
		if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == exitCodeNoValidToken {
			return false, nil
		}
		return false, fmt.Errorf("failed to check `cipd auth-info`: %w", err)
	}
	return true, nil
}

// Ensure runs cipd binary's ensure functionality over file. Fetched packages will be
// saved to projectRoot directory. Parameter timeout is in minutes.
func Ensure(jirix *jiri.X, file, projectRoot string, timeout uint) error {
	cipdPath, err := Bootstrap(jirix, jirix.CIPDPath())
	if err != nil {
		return err
	}
	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Minute)
	defer cancel()
	args := []string{
		"ensure",
		"-ensure-file", file,
		"-root", projectRoot,
		"-max-threads", strconv.Itoa(jirix.CipdMaxThreads),
	}

	// If jiri is *not* running with -v, use the less verbose cipd "warning"
	// log-level.
	if jirix.Logger.LoggerLevel < log.DebugLevel {
		args = append(args, "-log-level", "warning")
	}

	task := jirix.Logger.AddTaskMsg("Fetching CIPD packages")
	defer task.Done()
	jirix.Logger.Debugf("Invoke cipd with %v", args)

	// Construct arguments and invoke cipd for ensure file
	command := exec.CommandContext(ctx, cipdPath, args...)
	// Add User-Agent info for cipd
	command.Env = append(os.Environ(), "CIPD_HTTP_USER_AGENT_PREFIX="+getUserAgent())
	command.Stdin = os.Stdin
	command.Stdout = os.Stdout
	command.Stderr = os.Stderr

	err = command.Run()
	if ctx.Err() == context.DeadlineExceeded {
		err = ctx.Err()
	}
	return err
}

func EnsureFileVerify(jirix *jiri.X, file string) error {
	cipdPath, err := Bootstrap(jirix, jirix.CIPDPath())
	if err != nil {
		return err
	}
	args := []string{
		"ensure-file-verify",
		"-ensure-file", file,
	}
	// If jiri is *not* running with -v, use the less verbose cipd "warning"
	// log-level.
	if jirix.Logger.LoggerLevel < log.DebugLevel {
		args = append(args, "-log-level", "warning")
	}

	task := jirix.Logger.AddTaskMsg("Verifying CIPD ensure file")
	defer task.Done()
	jirix.Logger.Debugf("Invoke cipd with %v", args)

	// Construct arguments and invoke cipd for ensure file
	command := exec.Command(cipdPath, args...)
	var stdoutBuf, stderrBuf bytes.Buffer
	// Add User-Agent info for cipd
	command.Env = append(os.Environ(), "CIPD_HTTP_USER_AGENT_PREFIX="+getUserAgent())
	command.Stdin = os.Stdin
	// Redirect outputs since cipd will print verbose information even
	// if log-level is set to warning
	command.Stdout = &stdoutBuf
	command.Stderr = &stderrBuf

	if err := command.Run(); err != nil {
		jirix.Logger.Errorf("`cipd ensure-file-verify` failed: stdout: %s\nstderr: %s", stdoutBuf.String(), stderrBuf.String())
		return cipdManifestInvalidErr
	}

	return nil
}

// TODO: Using PackageLock in project package directly will cause an import
// cycle. Remove this type once we solve the this issue.

// PackageInstance describes package instance id information generated by cipd
// ensure-file-resolve. It is a copy of PackageLock type in project package.
type PackageInstance struct {
	PackageName string
	VersionTag  string
	InstanceID  string
}

// Resolve runs cipd binary's ensure-file-resolve functionality over file.
// It returns a slice containing resolved packages and cipd instance ids.
func Resolve(jirix *jiri.X, file string) ([]PackageInstance, error) {
	cipdPath, err := Bootstrap(jirix, jirix.CIPDPath())
	if err != nil {
		return nil, err
	}
	args := []string{"ensure-file-resolve", "-ensure-file", file, "-log-level", "warning"}
	jirix.Logger.Debugf("Invoke cipd with %v", args)

	command := exec.Command(cipdPath, args...)
	command.Env = append(os.Environ(), "CIPD_HTTP_USER_AGENT_PREFIX="+getUserAgent())
	var stdoutBuf, stderrBuf bytes.Buffer
	command.Stdin = os.Stdin
	// Redirect outputs since cipd will print verbose information even
	// if log-level is set to warning
	command.Stdout = &stdoutBuf
	command.Stderr = &stderrBuf
	if err := command.Run(); err != nil {
		jirix.Logger.Errorf("cipd returned error: %v", stderrBuf.String())
		return nil, err
	}

	// cipd generates the version file in the same directory of the ensure file
	// if no error is returned
	versionFile := file[:len(file)-len(".ensure")] + ".version"
	defer os.Remove(versionFile)
	return parseVersions(versionFile)
}

func parseVersions(file string) ([]PackageInstance, error) {
	versionReader, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer versionReader.Close()
	versionScanner := bufio.NewScanner(versionReader)
	// An example cipd version looks like:
	// ==========================================================
	// # Do not modify manually. All changes will be overwritten.
	// fuchsia/clang/linux-amd64
	// 	git_revision:280fa3c2d2ddb0b5dcb31113c0b1c2259982b7e7
	// 	eRoGS8qgx370QAIRgLDmbhpdPey8ti47B2Z3LMzwcXQC
	//
	// fuchsia/clang/mac-amd64
	// 	git_revision:280fa3c2d2ddb0b5dcb31113c0b1c2259982b7e7
	// 	BQhlnpoWG081CyLzA0zB1vCr8YPdb2DO2jnYe3Lsw4oC
	// ===========================================================
	// Parse version file using DFA

	const (
		stWaitingPkg = "a package name"
		stWaitingVer = "a package version"
		stWaitingIID = "an instance ID"
		stWaitingNL  = "a new line"
	)

	state := stWaitingPkg
	pkg := ""
	ver := ""
	iid := ""
	lineNo := 0
	makeError := func(fmtStr string, args ...interface{}) error {
		args = append([]interface{}{lineNo}, args...)
		return fmt.Errorf("failed to parse versions file (line %d): "+fmtStr, args...)
	}
	output := make([]PackageInstance, 0)
	for versionScanner.Scan() {
		lineNo++
		line := strings.TrimSpace(versionScanner.Text())
		// Comments are grammatically insignificant (unlike empty lines), so skip
		// the completely.
		if len(line) > 0 && line[0] == '#' {
			continue
		}

		switch state {
		case stWaitingPkg:
			if line == "" {
				continue // can have more than one empty line between triples
			}
			pkg = line
			state = stWaitingVer

		case stWaitingVer:
			if line == "" {
				return nil, makeError("expecting a version name, not a new line")
			}
			ver = line
			state = stWaitingIID

		case stWaitingIID:
			if line == "" {
				return nil, makeError("expecting an instance ID, not a new line")
			}
			iid = line
			output = append(output, PackageInstance{pkg, ver, iid})
			pkg, ver, iid = "", "", ""
			state = stWaitingNL

		case stWaitingNL:
			if line == "" {
				state = stWaitingPkg
				continue
			}
			return nil, makeError("expecting an empty line between each version definition triple")
		}
	}
	return output, nil
}

type packageFloatingRef struct {
	pkg      PackageInstance
	err      error
	floating bool
}

// CheckFloatingRefs determines if pkgs contains a floating ref which shouldn't
// be used normally.
func CheckFloatingRefs(jirix *jiri.X, pkgs map[PackageInstance]bool, plats map[PackageInstance][]Platform) error {
	if _, err := Bootstrap(jirix, jirix.CIPDPath()); err != nil {
		return err
	}

	jsonDir, err := ioutil.TempDir("", "jiri_cipd")
	if err != nil {
		return err
	}
	defer os.RemoveAll(jsonDir)

	c := make(chan packageFloatingRef)
	sem := semaphore.NewWeighted(10)
	var errBuf bytes.Buffer
	for k := range pkgs {
		plat, ok := plats[k]
		if !ok {
			return fmt.Errorf("Platforms for package \"%s\" is not found", k.PackageName)
		}
		go checkFloatingRefs(jirix, k, plat, jsonDir, sem, c)
	}

	for i := 0; i < len(pkgs); i++ {
		floatingRef := <-c
		pkgs[floatingRef.pkg] = floatingRef.floating
		if floatingRef.err != nil {
			errBuf.WriteString(fmt.Sprintf("error happened while checking package %q with version %q: %v\n", floatingRef.pkg.PackageName, floatingRef.pkg.VersionTag, floatingRef.err.Error()))
		}
	}

	if errBuf.Len() != 0 {
		// Remote trailing '\n'
		errBuf.Truncate(errBuf.Len() - 1)
		return errors.New(errBuf.String())
	}
	return nil
}

type describeJSON struct {
	Refs []refsJSON `json:"refs,omitempty"`
}

type refsJSON struct {
	Ref string `json:"ref,omitempty"`
}

func checkFloatingRefs(jirix *jiri.X, pkg PackageInstance, plats []Platform, jsonDir string, sem *semaphore.Weighted, c chan<- packageFloatingRef) {
	// cipd should already bootstrapped before calling
	// this function.
	sem.Acquire(context.Background(), 1)
	defer sem.Release(1)
	if cipdBinary == "" {
		c <- packageFloatingRef{
			pkg:      pkg,
			err:      errors.New("cipd is not bootstrapped when calling checkFloatingRefs"),
			floating: false,
		}
		return
	}
	// jsonFile will be cleaned up by caller.
	jsonFile, err := ioutil.TempFile(jsonDir, "cipd*.json")
	if err != nil {
		c <- packageFloatingRef{
			pkg:      pkg,
			err:      err,
			floating: false,
		}
		return
	}
	jsonFileName := jsonFile.Name()
	jsonFile.Close()

	// Remove ${platform}, ${os} ... from package name before calling cipd describe
	// as it will fail when these tags are not compatible with current host.
	pkgName := pkg.PackageName
	if MustExpand(pkgName) {
		expandedPkgName, err := Expand(pkgName, plats)
		if err != nil {
			c <- packageFloatingRef{
				pkg:      pkg,
				err:      err,
				floating: false,
			}
			return
		}
		if len(expandedPkgName) == 0 {
			c <- packageFloatingRef{
				pkg: pkg,
				// avoid using %q as we don't want escape characters in the output.
				err:      fmt.Errorf("cannot expand package \"%s\"", pkgName),
				floating: false,
			}
			return
		}
		pkgName = expandedPkgName[0]
	}

	args := []string{"describe", pkgName, "-version", pkg.VersionTag, "-json-output", jsonFileName}
	jirix.Logger.Debugf("Invoke cipd with %v", args)

	var stdoutBuf bytes.Buffer
	var stderrBuf bytes.Buffer
	command := exec.Command(cipdBinary, args...)
	command.Env = append(os.Environ(), "CIPD_HTTP_USER_AGENT_PREFIX="+getUserAgent())
	command.Stdin = os.Stdin
	command.Stdout = &stdoutBuf
	command.Stderr = &stderrBuf

	if err := command.Run(); err != nil {
		c <- packageFloatingRef{
			pkg:      pkg,
			err:      fmt.Errorf("cipd describe failed due to error: %v, stdout: %s\n, stderr: %s", err, stdoutBuf.String(), stderrBuf.String()),
			floating: false,
		}
		return
	}

	jsonData, err := ioutil.ReadFile(jsonFileName)
	if err != nil {
		c <- packageFloatingRef{
			pkg:      pkg,
			err:      err,
			floating: false,
		}
		return
	}
	// Example of generated JSON:
	// {
	// 	"result": {
	// 	  "pin": {
	// 		"package": "gn/gn/linux-amd64",
	// 		"instance_id": "4usiirrra6WbnCKgplRoiJ8EcAsCuqCOd_7tpf_yXrAC"
	// 	  },
	// 	  "registered_by": "user:infra-internal-gn-builder@chops-service-accounts.iam.gserviceaccount.com",
	// 	  "registered_ts": 1554328925,
	// 	  "refs": [
	// 		{
	// 		  "ref": "latest",
	// 		  "instance_id": "4usiirrra6WbnCKgplRoiJ8EcAsCuqCOd_7tpf_yXrAC",
	// 		  "modified_by": "user:infra-internal-gn-builder@chops-service-accounts.iam.gserviceaccount.com",
	// 		  "modified_ts": 1554328926
	// 		}
	// 	  ],
	// 	  "tags": [
	// 		{
	// 		  "tag": "git_repository:https://gn.googlesource.com/gn",
	// 		  "registered_by": "user:infra-internal-gn-builder@chops-service-accounts.iam.gserviceaccount.com",
	// 		  "registered_ts": 1554328925
	// 		},
	// 		{
	// 		  "tag": "git_revision:64b846c96daeb3eaf08e26d8a84d8451c6cb712b",
	// 		  "registered_by": "user:infra-internal-gn-builder@chops-service-accounts.iam.gserviceaccount.com",
	// 		  "registered_ts": 1554328925
	// 		}
	// 	  ]
	// 	}
	// }
	// Only "refs" is needed.

	var result struct {
		Result describeJSON `json:"result"`
	}

	if err := json.Unmarshal(jsonData, &result); err != nil {
		c <- packageFloatingRef{
			pkg:      pkg,
			err:      err,
			floating: false,
		}
		return
	}

	for _, v := range result.Result.Refs {
		if v.Ref == pkg.VersionTag {
			c <- packageFloatingRef{pkg: pkg, err: nil, floating: true}
			return
		}
	}
	c <- packageFloatingRef{pkg: pkg, err: nil, floating: false}
	return
}

// Platform contains the parameters for a "${platform}" template.
// The string value can be obtained by calling String().
type Platform struct {
	// OS defines the operating system of this platform. It can be any OS
	// supported by golang.
	OS string
	// Arch defines the CPU architecture of this platform. It can be any
	// architecture supported by golang.
	Arch string
}

// NewPlatform parses a platform string into Platform struct.
func NewPlatform(s string) (Platform, error) {
	fields := strings.Split(s, "-")
	if len(fields) != 2 {
		return Platform{"", ""}, fmt.Errorf("illegal platform %q", s)
	}
	return Platform{fields[0], fields[1]}, nil
}

// String generates a string represents the Platform in "OS"-"Arch" form.
func (p Platform) String() string {
	return p.OS + "-" + p.Arch
}

// Expander returns an Expander populated with p's fields.
func (p Platform) Expander() Expander {
	return Expander{
		"os":       p.OS,
		"arch":     p.Arch,
		"platform": p.String(),
	}
}

// Expander is a mapping of simple string substitutions which is used to
// expand cipd package name templates. For example:
//
//   ex, err := template.Expander{
//     "platform": "mac-amd64"
//   }.Expand("foo/${platform}")
//
// `ex` would be "foo/mac-amd64".
type Expander map[string]string

// Expand applies package template expansion rules to the package template,
//
// If err == ErrSkipTemplate, that means that this template does not apply to
// this os/arch combination and should be skipped.
//
// The expansion rules are as follows:
//   - "some text" will pass through unchanged
//   - "${variable}" will directly substitute the given variable
//   - "${variable=val1,val2}" will substitute the given variable, if its value
//     matches one of the values in the list of values. If the current value
//     does not match, this returns ErrSkipTemplate.
//
// Attempting to expand an unknown variable is an error.
// After expansion, any lingering '$' in the template is an error.
func (t Expander) Expand(template string) (pkg string, err error) {
	skip := false

	pkg = templateRE.ReplaceAllStringFunc(template, func(parm string) string {
		// ${...}
		contents := parm[2 : len(parm)-1]

		varNameValues := strings.SplitN(contents, "=", 2)
		if len(varNameValues) == 1 {
			// ${varName}
			if value, ok := t[varNameValues[0]]; ok {
				return value
			}

			err = fmt.Errorf("unknown variable in ${%s}", contents)
		}

		// ${varName=value,value}
		ourValue, ok := t[varNameValues[0]]
		if !ok {
			err = fmt.Errorf("unknown variable %q", parm)
			return parm
		}

		for _, val := range strings.Split(varNameValues[1], ",") {
			if val == ourValue {
				return ourValue
			}
		}
		skip = true
		return parm
	})
	if skip {
		err = ErrSkipTemplate
	}
	if err == nil && strings.ContainsRune(pkg, '$') {
		err = fmt.Errorf("unable to process some variables in %q", template)
	}
	return
}

// Expand method expands a cipdPath that contains templates such as ${platform}
// into concrete full paths. It might return an empty slice if platforms
// do not match the requirements in cipdPath.
func Expand(cipdPath string, platforms []Platform) ([]string, error) {
	output := make([]string, 0)
	//expanders := make([]Expander, 0)
	if !MustExpand(cipdPath) {
		output = append(output, cipdPath)
		return output, nil
	}

	for _, plat := range platforms {
		pkg, err := plat.Expander().Expand(cipdPath)
		if err == ErrSkipTemplate {
			continue
		}
		if err != nil {
			return nil, err
		}
		output = append(output, pkg)
	}
	return output, nil
}

// Decl method expands a cipdPath that contains ${platform}, ${os}, ${arch}
// with information in platforms. Unlike the Expand method which
// returns a list of expanded cipd paths, the Decl method only returns a
// single path containing all platforms. For example, if platforms contain
// "linux-amd64" and "linux-arm64", ${platform} will be replaced to
// ${platform=linux-amd64,linux-arm64}. This is a workaround for a limitation
// in 'cipd ensure-file-resolve' which requires the header of '.ensure' file
// to contain all available platforms. But in some cases, a package may miss
// a particular platform, which will cause a crash on this cipd command. By
// explicitly list all supporting platforms in the cipdPath, we can avoid
// crashing cipd.
func Decl(cipdPath string, platforms []Platform) (string, error) {
	if !MustExpand(cipdPath) || len(platforms) == 0 {
		return cipdPath, nil
	}

	osMap := make(map[string]bool)
	platMap := make(map[string]bool)
	archMap := make(map[string]bool)

	replacedOS := "${os="
	replacedArch := "${arch="
	replacedPlat := "${platform="

	for _, plat := range platforms {
		if _, ok := osMap[plat.OS]; !ok {
			replacedOS += plat.OS + ","
			osMap[plat.OS] = true
		}
		if _, ok := archMap[plat.Arch]; !ok {
			replacedArch += plat.Arch + ","
			archMap[plat.Arch] = true
		}
		if _, ok := platMap[plat.String()]; !ok {
			replacedPlat += plat.String() + ","
			platMap[plat.String()] = true
		}
	}
	replacedOS = replacedOS[:len(replacedOS)-1] + "}"
	replacedArch = replacedArch[:len(replacedArch)-1] + "}"
	replacedPlat = replacedPlat[:len(replacedPlat)-1] + "}"

	cipdPath = strings.Replace(cipdPath, "${os}", replacedOS, -1)
	cipdPath = strings.Replace(cipdPath, "${arch}", replacedArch, -1)
	cipdPath = strings.Replace(cipdPath, "${platform}", replacedPlat, -1)
	return cipdPath, nil
}

// MustExpand checks if template usages such as "${platform}" exist
// in cipdPath. If they exist, this function will return true. Otherwise
// it returns false.
func MustExpand(cipdPath string) bool {
	return templateRE.MatchString(cipdPath)
}

// DefaultPlatforms returns a slice of Platform objects that are currently
// validated by jiri.
func DefaultPlatforms() []Platform {
	return []Platform{
		{"linux", "amd64"},
		{"mac", "amd64"},
	}
}
