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

package project

import (
	"bytes"
	"context"
	"encoding/json"
	"encoding/xml"
	"errors"
	"fmt"
	"hash/fnv"
	"io"
	"io/ioutil"
	"net/url"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"regexp"
	"sort"
	"strings"
	"text/template"
	"time"

	"fuchsia.googlesource.com/jiri"
	"fuchsia.googlesource.com/jiri/cipd"
	"fuchsia.googlesource.com/jiri/envvar"
	"fuchsia.googlesource.com/jiri/gerrit"
	"fuchsia.googlesource.com/jiri/gitutil"
	"fuchsia.googlesource.com/jiri/retry"
	"golang.org/x/net/publicsuffix"
)

// Manifest represents a setting used for updating the universe.
type Manifest struct {
	Version          string        `xml:"version,attr,omitempty"`
	Attributes       string        `xml:"attributes,attr,omitempty"`
	Imports          []Import      `xml:"imports>import"`
	LocalImports     []LocalImport `xml:"imports>localimport"`
	Projects         []Project     `xml:"projects>project"`
	ProjectOverrides []Project     `xml:"overrides>project"`
	ImportOverrides  []Import      `xml:"overrides>import"`
	Hooks            []Hook        `xml:"hooks>hook"`
	Packages         []Package     `xml:"packages>package"`
	XMLName          struct{}      `xml:"manifest"`
}

// ManifestFromBytes returns a manifest parsed from data, with defaults filled
// in.
func ManifestFromBytes(data []byte) (*Manifest, error) {
	m := new(Manifest)
	if len(data) > 0 {
		if err := xml.Unmarshal(data, m); err != nil {
			return nil, err
		}
	}
	if err := m.fillDefaults(); err != nil {
		return nil, err
	}
	return m, nil
}

// ManifestFromFile returns a manifest parsed from the contents of filename,
// with defaults filled in.
//
// Note that unlike ProjectFromFile, ManifestFromFile does not convert project
// paths to absolute paths because it's possible to load a manifest with a
// specific root directory different from jirix.Root.  The usual way to load a
// manifest is through LoadManifest, which does absolutize the paths, and uses
// the correct root directory.
func ManifestFromFile(jirix *jiri.X, filename string) (*Manifest, error) {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, fmtError(err)
	}
	m, err := ManifestFromBytes(data)
	if err != nil {
		return nil, fmt.Errorf("invalid manifest %s: %v", filename, err)
	}
	return m, nil
}

var (
	newlineBytes        = []byte("\n")
	emptyImportsBytes   = []byte("\n  <imports></imports>\n")
	emptyProjectsBytes  = []byte("\n  <projects></projects>\n")
	emptyOverridesBytes = []byte("\n  <overrides></overrides>\n")
	emptyHooksBytes     = []byte("\n  <hooks></hooks>\n")
	emptyPackagesBytes  = []byte("\n  <packages></packages>\n")

	endElemBytes        = []byte("/>\n")
	endImportBytes      = []byte("></import>\n")
	endLocalImportBytes = []byte("></localimport>\n")
	endProjectBytes     = []byte("></project>\n")
	endHookBytes        = []byte("></hook>\n")
	endPackageBytes     = []byte("></package>\n")

	endImportSoloBytes  = []byte("></import>")
	endProjectSoloBytes = []byte("></project>")
	endElemSoloBytes    = []byte("/>")

	errGitHookNotRequired = errors.New("git hooks are not required")
)

const (
	fuchsiaGerritHost = "https://fuchsia-review.googlesource.com"
)

// deepCopy returns a deep copy of Manifest.
func (m *Manifest) deepCopy() *Manifest {
	x := new(Manifest)
	x.Imports = append([]Import(nil), m.Imports...)
	x.LocalImports = append([]LocalImport(nil), m.LocalImports...)
	x.Projects = append([]Project(nil), m.Projects...)
	x.ProjectOverrides = append([]Project(nil), m.ProjectOverrides...)
	x.ImportOverrides = append([]Import(nil), m.ImportOverrides...)
	x.Hooks = append([]Hook(nil), m.Hooks...)
	x.Packages = append([]Package(nil), m.Packages...)
	x.Version = m.Version
	x.Attributes = m.Attributes
	return x
}

// ToBytes returns m as serialized bytes, with defaults unfilled.
func (m *Manifest) ToBytes() ([]byte, error) {
	m = m.deepCopy() // avoid changing manifest when unfilling defaults.
	if err := m.unfillDefaults(); err != nil {
		return nil, err
	}
	data, err := xml.MarshalIndent(m, "", "  ")
	if err != nil {
		return nil, fmt.Errorf("manifest xml.Marshal failed: %v", err)
	}
	// It's hard (impossible?) to get xml.Marshal to elide some of the empty
	// elements, or produce short empty elements, so we post-process the data.
	data = bytes.Replace(data, emptyImportsBytes, newlineBytes, -1)
	data = bytes.Replace(data, emptyProjectsBytes, newlineBytes, -1)
	data = bytes.Replace(data, emptyOverridesBytes, newlineBytes, -1)
	data = bytes.Replace(data, emptyHooksBytes, newlineBytes, -1)
	data = bytes.Replace(data, emptyPackagesBytes, newlineBytes, -1)
	data = bytes.Replace(data, endImportBytes, endElemBytes, -1)
	data = bytes.Replace(data, endLocalImportBytes, endElemBytes, -1)
	data = bytes.Replace(data, endProjectBytes, endElemBytes, -1)
	data = bytes.Replace(data, endHookBytes, endElemBytes, -1)
	data = bytes.Replace(data, endPackageBytes, endElemBytes, -1)
	if !bytes.HasSuffix(data, newlineBytes) {
		data = append(data, '\n')
	}
	return data, nil
}

// ToFile writes the manifest m to a file with the given filename, with
// defaults unfilled and all project paths relative to the jiri root.
func (m *Manifest) ToFile(jirix *jiri.X, filename string) error {
	// Replace absolute paths with relative paths to make it possible to move
	// the root directory locally.
	projects := []Project{}
	for _, project := range m.Projects {
		if err := project.relativizePaths(jirix.Root); err != nil {
			return err
		}
		projects = append(projects, project)
	}
	// Sort the projects and hooks to ensure that the output of "jiri
	// snapshot" is deterministic.  Sorting the hooks by name allows
	// some control over the ordering of the hooks in case that is
	// necessary.
	sort.Sort(ProjectsByPath(projects))
	m.Projects = projects
	sort.Sort(HooksByName(m.Hooks))
	data, err := m.ToBytes()
	if err != nil {
		return err
	}
	return safeWriteFile(jirix, filename, data)
}

func (m *Manifest) fillDefaults() error {
	for index := range m.Imports {
		if err := m.Imports[index].fillDefaults(); err != nil {
			return err
		}
	}
	for index := range m.LocalImports {
		if err := m.LocalImports[index].validate(); err != nil {
			return err
		}
	}
	for index := range m.Projects {
		if err := m.Projects[index].fillDefaults(); err != nil {
			return err
		}
	}
	for index := range m.ProjectOverrides {
		if err := m.ProjectOverrides[index].fillDefaults(); err != nil {
			return err
		}
	}
	for index := range m.ImportOverrides {
		if err := m.ImportOverrides[index].fillDefaults(); err != nil {
			return err
		}
	}
	return nil
}

func (m *Manifest) unfillDefaults() error {
	for index := range m.Imports {
		if err := m.Imports[index].unfillDefaults(); err != nil {
			return err
		}
	}
	for index := range m.LocalImports {
		if err := m.LocalImports[index].validate(); err != nil {
			return err
		}
	}
	for index := range m.Projects {
		if err := m.Projects[index].unfillDefaults(); err != nil {
			return err
		}
	}
	for index := range m.ProjectOverrides {
		if err := m.ProjectOverrides[index].unfillDefaults(); err != nil {
			return err
		}
	}
	for index := range m.ImportOverrides {
		if err := m.ImportOverrides[index].unfillDefaults(); err != nil {
			return err
		}
	}
	return nil
}

// Import represents a remote manifest import.
type Import struct {
	// Manifest file to use from the remote manifest project.
	Manifest string `xml:"manifest,attr,omitempty"`
	// Name is the name of the remote manifest project, used to determine the
	// project key.
	Name string `xml:"name,attr,omitempty"`
	// Remote is the remote manifest project to import.
	Remote string `xml:"remote,attr,omitempty"`
	// Revision is the revison to checkout,
	// this takes precedence over RemoteBranch
	Revision string `xml:"revision,attr,omitempty"`
	// RemoteBranch is the name of the remote branch to track.
	RemoteBranch string `xml:"remotebranch,attr,omitempty"`
	// Root path, prepended to all project paths specified in the manifest file.
	Root    string   `xml:"root,attr,omitempty"`
	XMLName struct{} `xml:"import"`
}

func (i *Import) fillDefaults() error {
	if i.RemoteBranch == "" {
		i.RemoteBranch = "master"
	}
	if i.Revision == "" {
		i.Revision = "HEAD"
	}
	return i.validate()
}

func (i *Import) RemoveDefaults() {
	if i.RemoteBranch == "master" {
		i.RemoteBranch = ""
	}
	if i.Revision == "HEAD" {
		i.Revision = ""
	}
}

func (i *Import) unfillDefaults() error {
	i.RemoveDefaults()
	return i.validate()
}

func (i *Import) validate() error {
	if i.Manifest == "" || i.Remote == "" {
		return fmt.Errorf("bad import: both manifest and remote must be specified")
	}
	return nil
}

func (i *Import) toProject(path string) (Project, error) {
	p := Project{
		Name:         i.Name,
		Path:         path,
		Remote:       i.Remote,
		Revision:     i.Revision,
		RemoteBranch: i.RemoteBranch,
	}
	err := p.fillDefaults()
	return p, err
}

// ProjectKey returns the unique ProjectKey for the imported project.
func (i *Import) ProjectKey() ProjectKey {
	return MakeProjectKey(i.Name, i.Remote)
}

// projectKeyFileName returns a file name based on the ProjectKey.
func (i *Import) projectKeyFileName() string {
	// TODO(toddw): Disallow weird characters from project names.
	hash := fnv.New64a()
	hash.Write([]byte(i.ProjectKey()))
	return fmt.Sprintf("%s_%x", i.Name, hash.Sum64())
}

// cycleKey returns a key based on the remote and manifest, used for
// cycle-detection.  It's only valid for new-style remote imports; it's empty
// for the old-style local imports.
func (i *Import) cycleKey() string {
	if i.Remote == "" {
		return ""
	}
	// We don't join the remote and manifest with a slash or any other url-safe
	// character, since that might not be unique.  E.g.
	//   remote:   https://foo.com/a/b    remote:   https://foo.com/a
	//   manifest: c                      manifest: b/c
	// In both cases, the key would be https://foo.com/a/b/c.
	return i.Remote + " + " + i.Manifest
}

func (i *Import) update(o *Import) {
	if o.Manifest != "" {
		i.Manifest = o.Manifest
	}
	if o.Name != "" {
		i.Name = o.Name
	}
	if o.Remote != "" {
		i.Remote = o.Remote
	}
	if o.Revision != "" {
		i.Revision = o.Revision
	}
	if o.RemoteBranch != "" {
		i.RemoteBranch = o.RemoteBranch
	}
	if o.Root != "" {
		i.Root = o.Root
	}
}

// LocalImport represents a local manifest import.
type LocalImport struct {
	// Manifest file to import from.
	File    string   `xml:"file,attr,omitempty"`
	XMLName struct{} `xml:"localimport"`
}

func (i *LocalImport) validate() error {
	if i.File == "" {
		return fmt.Errorf("bad localimport: must specify file: %+v", *i)
	}
	return nil
}

type LocalConfig struct {
	Ignore   bool     `xml:"ignore"`
	NoUpdate bool     `xml:"no-update"`
	NoRebase bool     `xml:"no-rebase"`
	XMLName  struct{} `xml:"config"`
}

// Reads localConfig from given reader. Returns incorrect bytes
func (lc *LocalConfig) ReadFrom(r io.Reader) (int64, error) {
	return 1, xml.NewDecoder(r).Decode(lc)
}

func LocalConfigFromFile(jirix *jiri.X, filename string) (LocalConfig, error) {
	var lc LocalConfig
	f, err := os.Open(filename)
	if os.IsNotExist(err) {
		return lc, nil
	} else if err != nil {
		return lc, fmtError(err)
	}
	_, err = lc.ReadFrom(f)
	return lc, err
}

// Writes the localConfig to given writer. Returns incorrect bytes
func (lc *LocalConfig) WriteTo(writer io.Writer) (int64, error) {
	encoder := xml.NewEncoder(writer)
	encoder.Indent("", " ")
	return 1, encoder.Encode(lc)
}

func (lc *LocalConfig) ToFile(jirix *jiri.X, filename string) error {
	if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
		return fmtError(err)
	}
	writer, err := os.Create(filename)
	if err != nil {
		return fmtError(err)
	}
	defer writer.Close()
	_, err = lc.WriteTo(writer)
	return err
}

func WriteLocalConfig(jirix *jiri.X, project Project, lc LocalConfig) error {
	configFile := filepath.Join(project.Path, jiri.ProjectMetaDir, jiri.ProjectConfigFile)
	return lc.ToFile(jirix, configFile)
}

// Hook represents a hook to run
type Hook struct {
	Name        string   `xml:"name,attr"`
	Action      string   `xml:"action,attr"`
	ProjectName string   `xml:"project,attr"`
	XMLName     struct{} `xml:"hook"`
	ActionPath  string   `xml:"-"`
}

// HookKey is a unique string for a project.
type HookKey string

type Hooks map[HookKey]Hook

// Key returns the unique HookKey for the hook.
func (h Hook) Key() HookKey {
	return MakeHookKey(h.Name, h.ProjectName)
}

// MakeHookKey returns the hook key, given the hook and project name.
func MakeHookKey(name, projectName string) HookKey {
	return HookKey(name + KeySeparator + projectName)
}

func (h *Hook) validate() error {
	if strings.Contains(h.Name, KeySeparator) {
		return fmt.Errorf("bad hook: name cannot contain %q: %+v", KeySeparator, *h)
	}
	if strings.Contains(h.ProjectName, KeySeparator) {
		return fmt.Errorf("bad hook: project cannot contain %q: %+v", KeySeparator, *h)
	}
	return nil
}

// HooksByName implements the Sort interface. It sorts Hooks by the Name
// and ProjectName field.
type HooksByName []Hook

func (hooks HooksByName) Len() int {
	return len(hooks)
}
func (hooks HooksByName) Swap(i, j int) {
	hooks[i], hooks[j] = hooks[j], hooks[i]
}
func (hooks HooksByName) Less(i, j int) bool {
	if hooks[i].Name == hooks[j].Name {
		return hooks[i].ProjectName < hooks[j].ProjectName
	}
	return hooks[i].Name < hooks[j].Name
}

// Package struct represents the <package> tag in manifest files.
type Package struct {
	// Name represents the remote cipd path of the package.
	Name string `xml:"name,attr"`

	// Version represents the version tag of the cipd package.
	Version string `xml:"version,attr"`

	// Path stores the local path of fetched cipd package.
	Path string `xml:"path,attr,omitempty"`

	// Internal marks if this package require special permission
	// for access
	Internal bool `xml:"internal,attr,omitempty"`

	// Platforms defines the available platforms for this cipd package.
	Platforms string `xml:"platforms,attr,omitempty"`

	// Flag defines the content that should be written to a file when
	// this package is successfully fetched.
	Flag string `xml:"flag,attr,omitempty"`

	// Attributes store the the list attributes for this package.
	// When it starts with "+", a computed default attributes will
	// be appended.
	Attributes string `xml:"attributes,attr,omitempty"`

	// Instances store the known instance ids for this package.
	// It is mainly used by snapshot file.
	Instances []PackageInstance `xml:"instance"`
	XMLName   struct{}          `xml:"package"`

	// ComputedAttributes stores computed attributes object
	// which is easiler to perform matching and comparing.
	ComputedAttributes attributes `xml:"-"`

	// ManifestPath stores the absolute path of the manifest.
	ManifestPath string `xml:"-"`
}

type PackageKey string

type Packages map[PackageKey]Package

type PackageKeys []PackageKey

func (p Package) Key() PackageKey {
	return PackageKey(p.Path + KeySeparator + p.Name)
}

func (pks PackageKeys) Len() int           { return len(pks) }
func (pks PackageKeys) Less(i, j int) bool { return string(pks[i]) < string(pks[j]) }
func (pks PackageKeys) Swap(i, j int)      { pks[i], pks[j] = pks[j], pks[i] }

// FilterACL returns a new Packages map without any inaccessible packages.
func (p *Packages) FilterACL(jirix *jiri.X) (Packages, bool, error) {
	// Perform ACL checks on internal projects
	pkgACLMap := make(map[string]bool)
	hasInternal := false
	for _, pkg := range *p {
		pkg.Name = strings.TrimRight(pkg.Name, "/")
		if pkg.Internal {
			hasInternal = true
			pkgACLMap[pkg.Name] = false
		}
	}
	if len(pkgACLMap) != 0 {
		if err := cipd.CheckPackageACL(jirix, pkgACLMap); err != nil {
			return nil, false, err
		}
	}
	retPkgs := make(Packages)
	for _, pkg := range *p {
		if val, ok := pkgACLMap[pkg.Name]; ok && !val {
			continue
		}
		retPkgs[pkg.Key()] = pkg
	}
	return retPkgs, hasInternal, nil
}

type PackageInstance struct {
	Name    string   `xml:"name,attr"`
	ID      string   `xml:"id,attr"`
	XMLName struct{} `xml:"instance"`
}

// FillDefaults function fills default platforms information into
// Package struct if it is not defined and path is using template.
func (p *Package) FillDefaults() error {
	if cipd.MustExpand(p.Name) && p.Platforms == "" {
		for _, v := range cipd.DefaultPlatforms() {
			p.Platforms += v.String() + ","
		}
		if p.Platforms[len(p.Platforms)-1] == ',' {
			p.Platforms = p.Platforms[:len(p.Platforms)-1]
		}
	}
	return nil
}

// GetPath returns the relative path that Package p should be
// downloaded to.
func (p *Package) GetPath() (string, error) {
	if p.Path == "" {
		cipdPath := p.Name
		// Replace template with current platform information.
		// If failed, skip filling in default path.
		if cipd.MustExpand(cipdPath) {
			expanded, err := cipd.Expand(cipdPath, []cipd.Platform{cipd.CipdPlatform})
			if err != nil {
				return "", err
			}
			if len(expanded) > 0 {
				cipdPath = expanded[0]
			}
		}
		if !cipd.MustExpand(cipdPath) {
			base := path.Base(cipdPath)
			if _, err := cipd.NewPlatform(base); err == nil {
				// base is the name for a platform
				base = filepath.Join(path.Base(path.Dir(cipdPath)), base)
			}
			return filepath.Join("prebuilt", base), nil
		}
		return "prebuilt", nil
	}
	return p.Path, nil
}

// GetPlatforms returns the platforms information of
// this Package struct.
func (p *Package) GetPlatforms() ([]cipd.Platform, error) {
	if err := p.FillDefaults(); err != nil {
		return nil, err
	}
	retList := make([]cipd.Platform, 0)
	platStrs := strings.Split(p.Platforms, ",")
	for _, platStr := range platStrs {
		if platStr == "" {
			continue
		}
		plat, err := cipd.NewPlatform(platStr)
		if err != nil {
			return nil, err
		}
		retList = append(retList, plat)
	}
	return retList, nil
}

// LoadManifest loads the manifest, starting with the .jiri_manifest file,
// resolving remote and local imports.  Returns the projects specified by
// the manifest.
//
// WARNING: LoadManifest cannot be run multiple times in parallel!  It invokes
// git operations which require a lock on the filesystem.  If you see errors
// about ".git/index.lock exists", you are likely calling LoadManifest in
// parallel.
func LoadManifest(jirix *jiri.X) (Projects, Hooks, Packages, error) {
	jirix.TimerPush("load manifest")
	defer jirix.TimerPop()
	file := jirix.JiriManifestFile()
	localProjects, err := LocalProjects(jirix, FastScan)
	if err != nil {
		return nil, nil, nil, err
	}
	return LoadManifestFile(jirix, file, localProjects, false)
}

func (ld *loader) warnOverrides(jirix *jiri.X) {
	if len(ld.ProjectOverrides) != 0 {
		for _, v := range ld.ProjectOverrides {
			revision := v.Revision
			if revision == "" {
				revision = "HEAD"
			}
			jirix.Logger.Warningf("Project %s(remote: %s) is pinned to revision %s, if that is not what you want, please run \"jiri override --delete %s %s\" to unpin it.", v.Name, v.Remote, revision, v.Name, v.Remote)
			jirix.OverrideWarned = true
		}
	}
	if len(ld.ImportOverrides) != 0 {
		for _, v := range ld.ImportOverrides {
			revision := v.Revision
			if revision == "" {
				revision = "HEAD"
			}
			jirix.Logger.Warningf("Import %s(remote: %s) is pinned to revision %s, if that is not what you want, please run \"jiri override --import-manifest=%s --delete %s %s\" to unpin it.", v.Name, v.Remote, revision, v.Manifest, v.Name, v.Remote)
			jirix.OverrideWarned = true
		}
	}
}

func (ld *loader) enforceLocks(jirix *jiri.X) error {
	enforceProjLocks := func(jirix *jiri.X) (err error) {
		for _, v := range ld.Projects {
			if projectLock, ok := ld.ProjectLocks[ProjectLockKey(v.Key())]; ok {
				if v.Revision == "" || v.Revision == "HEAD" {
					v.Revision = projectLock.Revision
					ld.Projects[v.Key()] = v
				} else if v.Revision != projectLock.Revision {
					s := fmt.Sprintf("project %+v has conflicting revisions in manifest and jiri.lock: %s:%s", v, v.Revision, projectLock.Revision)
					jirix.Logger.Debugf(s)
					err = errors.New(s)
				}
			}
		}
		return
	}

	enforcePkgLocks := func(jirix *jiri.X) (err error) {
		usedPkgLocks := make(map[PackageLockKey]bool)
		for k := range ld.PackageLocks {
			usedPkgLocks[k] = false
		}
		for _, v := range ld.Packages {
			plats, err := v.GetPlatforms()
			if err != nil {
				return err
			}
			pkgs, err := cipd.Expand(v.Name, plats)
			if err != nil {
				return err
			}
			for _, pkg := range pkgs {
				if pkgLock, ok := ld.PackageLocks[PackageLockKey(pkg+KeySeparator+v.Version)]; ok {
					if pkgLock.VersionTag != v.Version && !jirix.IgnoreLockConflicts {
						// Package version conflicts detected. Treated it as an error.
						s := fmt.Sprintf("package %q has conflicting version in manifest and jiri.lock: %s:%s", v.Name, v.Version, pkgLock.VersionTag)
						jirix.Logger.Debugf(s)
						err = errors.New(s)
					}
					ins := PackageInstance{
						Name: pkgLock.PackageName,
						ID:   pkgLock.InstanceID,
					}
					v.Instances = append(v.Instances, ins)
					ld.Packages[v.Key()] = v
					usedPkgLocks[pkgLock.Key()] = true
				} else {
					jirix.Logger.Debugf("Package %q is not found in jiri.lock", pkg)
				}
			}
			if err != nil {
				return err
			}
		}
		for k, v := range usedPkgLocks {
			if !v {
				jirix.Logger.Debugf("PackageLock %v is not used", k)
			}
		}
		return
	}

	if err := enforceProjLocks(jirix); err != nil {
		return err
	}

	if err := enforcePkgLocks(jirix); err != nil {
		return err
	}
	return nil
}

// LoadManifestFile loads the manifest starting with the given file, resolving
// remote and local imports.  Local projects are used to resolve remote imports;
// if nil, encountering any remote import will result in an error.
//
// WARNING: LoadManifestFile cannot be run multiple times in parallel!  It
// invokes git operations which require a lock on the filesystem.  If you see
// errors about ".git/index.lock exists", you are likely calling
// LoadManifestFile in parallel.
func LoadManifestFile(jirix *jiri.X, file string, localProjects Projects, localManifest bool) (Projects, Hooks, Packages, error) {
	ld := newManifestLoader(localProjects, false, file)
	if err := ld.Load(jirix, "", "", file, "", "", "", localManifest); err != nil {
		return nil, nil, nil, err
	}
	jirix.AddCleanupFunc(ld.cleanup)
	if jirix.LockfileEnabled {
		if err := ld.enforceLocks(jirix); err != nil {
			return nil, nil, nil, err
		}
	}
	if !jirix.OverrideWarned {
		ld.warnOverrides(jirix)
	}
	ld.GenerateGitAttributesForProjects(jirix)
	return ld.Projects, ld.Hooks, ld.Packages, nil
}

// LoadUpdatedManifest loads an updated manifest starting with the .jiri_manifest file for localProjects. It will use
// local manifest files instead of manifest files in remote repositories if localManifest is set to true.
func LoadUpdatedManifest(jirix *jiri.X, localProjects Projects, localManifest bool) (Projects, Hooks, Packages, error) {
	jirix.TimerPush("load updated manifest")
	defer jirix.TimerPop()
	ld := newManifestLoader(localProjects, true, jirix.JiriManifestFile())
	if err := ld.Load(jirix, "", "", jirix.JiriManifestFile(), "", "", "", localManifest); err != nil {
		return nil, nil, nil, err
	}
	jirix.AddCleanupFunc(ld.cleanup)
	if jirix.LockfileEnabled {
		if err := ld.enforceLocks(jirix); err != nil {
			return nil, nil, nil, err
		}
	}
	if !jirix.OverrideWarned {
		ld.warnOverrides(jirix)
	}
	ld.GenerateGitAttributesForProjects(jirix)
	return ld.Projects, ld.Hooks, ld.Packages, nil
}

// ResolveImplicitPackageVersions resolves the version field of packages if it
// pins to a project's revision hash
func ResolveImplicitPackageVersions(jirix *jiri.X, projects Projects, pkgs Packages) (Packages, error) {
	// Example:
	// <package name="fuchsia/dart-sdk/${platform}"
	//          path="third_party/dart/tools/sdks/dart-sdk"
	//          version="git_revision:{{(index .Projects &quot;dart/sdk&quot;).Revision}}"/>
	// The fuchsia/dart-sdk package is pinned to current dart/sdk project's Revision
	templateRE := regexp.MustCompile(`{{[^}]*}}`)
	var projMap struct {
		Projects map[string]Project
	}
	retPkgs := make(Packages)
	for k, v := range pkgs {
		retPkgs[k] = v
	}
	projMap.Projects = make(map[string]Project)
	for _, proj := range projects {
		if v, ok := projMap.Projects[proj.Name]; ok {
			// Just a warning since jiri could handle projects with duplicated names.
			jirix.Logger.Warningf("Found more than 1 projects have the same name: %+v:%+v", proj, v)
		}
		projMap.Projects[proj.Name] = proj
	}

	for _, pkg := range pkgs {
		if !templateRE.MatchString(pkg.Version) {
			continue
		}
		tpl, err := template.New("version").Parse(pkg.Version)
		if err != nil {
			return nil, err
		}
		var verBuf bytes.Buffer
		if err := tpl.Execute(&verBuf, &projMap); err != nil {
			return nil, err
		}
		pkg.Version = verBuf.String()
		retPkgs[pkg.Key()] = pkg
	}
	return retPkgs, nil
}

// resovlePackageLocks resolves instance ids using versions described in given
// pkgs using cipd.
func resolvePackageLocks(jirix *jiri.X, projects Projects, pkgs Packages) (PackageLocks, error) {
	jirix.TimerPush("resolve instance id for cipd packages")
	defer jirix.TimerPop()

	pkgs, _, err := pkgs.FilterACL(jirix)
	if err != nil {
		return nil, err
	}

	ensureFilePath, err := generateEnsureFile(jirix, projects, pkgs, false)
	if err != nil {
		return nil, err
	}
	defer os.Remove(ensureFilePath)

	pkgInstances, err := cipd.Resolve(jirix, ensureFilePath)
	if err != nil {
		return nil, err
	}
	// TODO: Remove this boilerplate once we have a better package
	// layout that doesn't cause import cycles
	pkgLocks := make(PackageLocks)
	for _, val := range pkgInstances {
		pkgLock := PackageLock{
			PackageName: val.PackageName,
			VersionTag:  val.VersionTag,
			InstanceID:  val.InstanceID,
		}
		pkgLocks[pkgLock.Key()] = pkgLock
	}

	return pkgLocks, nil
}

// resolveProjectLocks resolves project revisions <project> tags in manifests
func resolveProjectLocks(jirix *jiri.X, projects Projects) (ProjectLocks, error) {
	projectLocks := make(ProjectLocks)
	for _, v := range projects {
		projectLock := ProjectLock{v.Remote, v.Name, v.Revision}
		projectLocks[projectLock.Key()] = projectLock
	}
	return projectLocks, nil
}

// FetchPackages fetches prebuilt packages described in given pkgs using cipd.
// Parameter fetchTimeout is in minutes.
func FetchPackages(jirix *jiri.X, projects Projects, pkgs Packages, fetchTimeout uint) error {
	jirix.TimerPush("fetch cipd packages")
	defer jirix.TimerPop()

	pkgsWAccess, hasInternalPkgs, err := pkgs.FilterACL(jirix)
	if err != nil {
		return err
	}

	ensureFilePath, err := generateEnsureFile(jirix, projects, pkgsWAccess, !jirix.LockfileEnabled || jirix.UsingSnapshot)
	if err != nil {
		return err
	}
	defer os.Remove(ensureFilePath)

	if jirix.LockfileEnabled && !jirix.UsingSnapshot {
		versionFilePath, err := generateVersionFile(jirix, ensureFilePath, pkgs)
		if err != nil {
			return err
		}
		defer os.Remove(versionFilePath)
	}

	if err := cipd.Ensure(jirix, ensureFilePath, jirix.Root, fetchTimeout); err != nil {
		return err
	}

	if hasInternalPkgs {
		if err := writePackageJSON(jirix, len(pkgs) == len(pkgsWAccess)); err != nil {
			return err
		}
	}

	// Write explict flags.
	if err := WritePackageFlags(jirix, pkgs, pkgsWAccess); err != nil {
		return err
	}

	if len(pkgs) > len(pkgsWAccess) {
		cipdLoggedIn, err := cipd.CheckLoggedIn(jirix)
		if err != nil {
			return err
		}
		if !cipdLoggedIn {
			jirix.Logger.Warningf("Some packages are skipped by cipd due to lack of access, you might want to run \"%s auth-login\" and try again", jirix.CIPDPath())
		}
	}
	return nil
}

// WritePackageFlags write flag files into project directory using in "flag"
// attribute from pkgs.
func WritePackageFlags(jirix *jiri.X, pkgs, pkgsWA Packages) error {
	// The flag attribute has a format of $FILE_NAME|$FLAG_SUCCESSFUL|$FLAG_FAILED
	// When a package is successfully downloaded, jiri will write $FLAG_SUCCESSFUL
	// to $FILE_NAME. If the package is not downloaded due to access reasons,
	// jiri will write $FLAG_FAILED to $FILE_NAME.
	// '|' is a forbidden symbol in Windows path, which is unlikely
	// to be used by path.

	flagMap := make(map[string]string)
	fill := func(file, flag string) error {
		if v, ok := flagMap[file]; ok {
			if v != flag {
				return fmt.Errorf("encountered conflicting flags for file %q: %q conflicts with %q", file, v, flag)
			}
		} else {
			flagMap[file] = flag
		}
		return nil
	}

	for k, v := range pkgs {
		if v.Flag == "" {
			continue
		}
		fields := strings.Split(v.Flag, "|")
		if len(fields) != 3 {
			return fmt.Errorf("unknown package flag format found in package %+v", v)
		}
		if _, ok := pkgsWA[k]; ok {
			// package is successfully fetched, write successful flag.
			if err := fill(fields[0], fields[1]); err != nil {
				return err
			}
		} else {
			// package is failed to fetched, write failed flag.
			if err := fill(fields[0], fields[2]); err != nil {
				return err
			}
		}
	}

	var writeErrorBuf bytes.Buffer
	for k, v := range flagMap {
		if err := ioutil.WriteFile(filepath.Join(jirix.Root, k), []byte(v), 0644); err != nil {
			writeErrorBuf.WriteString(fmt.Sprintf("write package flag %q to file %q failed due to error: %v\n", v, k, err))
		}
	}
	if writeErrorBuf.Len() > 0 {
		return errors.New(writeErrorBuf.String())
	}
	return nil
}

// GenerateJSON generates a json file which contains fetched
// packages.
func writePackageJSON(jirix *jiri.X, access bool) error {
	var internalAccess struct {
		Access bool `json:"internal_access"`
	}
	internalAccess.Access = access
	jsonData, err := json.MarshalIndent(&internalAccess, "", "    ")
	if err != nil {
		return err
	}
	if jirix.PrebuiltJSON == "" {
		// Skip json file creation if PrebuiltJSON is not set.
		return nil
	}
	return ioutil.WriteFile(filepath.Join(jirix.RootMetaDir(), jirix.PrebuiltJSON), jsonData, 0644)
}

func generateEnsureFile(jirix *jiri.X, projects Projects, pkgs Packages, ignoreCryptoCheck bool) (string, error) {
	pkgs, err := ResolveImplicitPackageVersions(jirix, projects, pkgs)
	if err != nil {
		return "", err
	}
	ensureFile, err := ioutil.TempFile("", "jiri*.ensure")
	if err != nil {
		return "", fmt.Errorf("not able to create tmp file: %v", err)
	}
	defer ensureFile.Close()
	ensureFilePath := ensureFile.Name()

	// Write header information
	// TODO: add "verfy_platform" attribute to each package tag
	// to avoid hardcoding platform names in Jiri
	var ensureFileBuf bytes.Buffer
	if !ignoreCryptoCheck {
		// Collect platforms used by this project
		allPlats := make(map[string]cipd.Platform)
		// CIPD ensure-file-resolve requires $VerifiedPlatform to be present
		// even if the package name is not using ${platform} template.
		// Put DefaultPlatforms into header to walkaround this issue.
		for _, plat := range cipd.DefaultPlatforms() {
			allPlats[plat.String()] = plat
		}
		for _, pkg := range pkgs {
			plats, err := pkg.GetPlatforms()
			if err != nil {
				return "", err
			}
			for _, plat := range plats {
				allPlats[plat.String()] = plat
			}
		}

		for _, plat := range allPlats {
			ensureFileBuf.WriteString(fmt.Sprintf("$VerifiedPlatform %s\n", plat))
		}
		versionFileName := ensureFilePath[:len(ensureFilePath)-len(".ensure")] + ".version"
		ensureFileBuf.WriteString("$ResolvedVersions " + versionFileName + "\n")
	}
	if jirix.CipdParanoidMode {
		ensureFileBuf.WriteString("$ParanoidMode CheckPresence\n")
	}
	ensureFileBuf.WriteString("\n")

	for _, pkg := range pkgs {

		cipdDecl, err := pkg.cipdDecl(jirix)
		if err != nil {
			return "", err
		}
		ensureFileBuf.WriteString(cipdDecl)
		ensureFileBuf.WriteString("\n")
	}

	jirix.Logger.Debugf("Generated ensure file content:\n%v", ensureFileBuf.String())
	if _, err := ensureFileBuf.WriteTo(ensureFile); err != nil {
		return "", err
	}
	if err := ensureFile.Sync(); err != nil {
		return "", err
	}

	return ensureFilePath, nil
}

func (p *Package) cipdDecl(jirix *jiri.X) (string, error) {
	var buf bytes.Buffer
	// Write "@Subdir" line to cipd declaration
	subdir, err := p.GetPath()
	if err != nil {
		return "", err
	}
	tmpl, err := template.New("pack").Parse(subdir)
	if err != nil {
		return "", fmt.Errorf("parsing package path %q failed", subdir)
	}
	var subdirBuf bytes.Buffer
	// subdir is using fuchsia platform format instead of
	// using cipd platform format
	tmpl.Execute(&subdirBuf, cipd.FuchsiaPlatform(cipd.CipdPlatform))
	subdir = subdirBuf.String()
	buf.WriteString(fmt.Sprintf("@Subdir %s\n", subdir))
	// Write package version line to cipd declaration
	plats, err := p.GetPlatforms()
	if err != nil {
		return "", err
	}
	var cipdPath, version string
	version = p.Version
	cipdPath, err = cipd.Decl(p.Name, plats)
	if err != nil {
		return "", err
	}
	if jirix.UsingSnapshot && len(p.Instances) != 0 {
		candPath, err := cipd.Expand(p.Name, []cipd.Platform{cipd.CipdPlatform})
		if err != nil {
			return "", err
		}
		if len(candPath) > 0 {
			for _, inst := range p.Instances {
				if inst.Name == candPath[0] {
					cipdPath = candPath[0]
					version = inst.ID
					break
				}
			}
		} else {
			// cipd.Expand failed expand
			// This may happen if the cipdPath does not allow platform
			// in cipd.CipdPlatform. E.g.
			// "example/linux-${arch=amd64}" expanded with "linux-arm64".
			// Leave a log in Debug log.
			jirix.Logger.Debugf("cipd.Expand failed to expand cipd path %q using platforms %v", p.Name, cipd.CipdPlatform)
		}
	}
	buf.WriteString(fmt.Sprintf("%s %s\n", cipdPath, version))
	return buf.String(), nil
}

func generateVersionFile(jirix *jiri.X, ensureFile string, pkgs Packages) (string, error) {
	versionFileName := ensureFile[:len(ensureFile)-len(".ensure")] + ".version"

	var versionFileBuf bytes.Buffer
	// Just pour everything in pkgLocks into version file without matching package
	// names. cipd will do the matching for us.
	for _, pkg := range pkgs {
		jirix.Logger.Debugf("Generate version file using %+v", pkg)
		for _, ins := range pkg.Instances {
			decl := fmt.Sprintf("\n%s\n\t%s\n\t%s\n", ins.Name, pkg.Version, ins.ID)
			versionFileBuf.WriteString(decl)
		}
	}
	jirix.Logger.Debugf("Generated version file content:\n%v", versionFileBuf.String())
	return versionFileName, ioutil.WriteFile(versionFileName, versionFileBuf.Bytes(), 0655)
}

// RunHooks runs all given hooks.
func RunHooks(jirix *jiri.X, hooks Hooks, runHookTimeout uint) error {
	jirix.TimerPush("run hooks")
	defer jirix.TimerPop()
	jirix.Logger.Debugf("Running Jiri hooks")
	defer jirix.Logger.Debugf("Running Jiri ")
	type result struct {
		outFile *os.File
		errFile *os.File
		err     error
	}
	ch := make(chan result)
	tmpDir, err := ioutil.TempDir("", "run-hooks")
	if err != nil {
		return fmt.Errorf("not able to create tmp dir: %v", err)
	}
	defer os.RemoveAll(tmpDir)
	for _, hook := range hooks {
		go func(hook Hook) {
			logStr := fmt.Sprintf("running hook(%s) for project %q", hook.Name, hook.ProjectName)
			jirix.Logger.Debugf(logStr)
			task := jirix.Logger.AddTaskMsg(logStr)
			defer task.Done()
			outFile, err := ioutil.TempFile(tmpDir, hook.Name+"-out")
			if err != nil {
				ch <- result{nil, nil, fmtError(err)}
				return
			}
			errFile, err := ioutil.TempFile(tmpDir, hook.Name+"-err")
			if err != nil {
				ch <- result{nil, nil, fmtError(err)}
				return
			}

			fmt.Fprintf(outFile, "output for hook(%v) for project %q\n", hook.Name, hook.ProjectName)
			fmt.Fprintf(errFile, "Error for hook(%v) for project %q\n", hook.Name, hook.ProjectName)
			cmdLine := filepath.Join(hook.ActionPath, hook.Action)
			err = retry.Function(jirix, func() error {
				ctx, cancel := context.WithTimeout(context.Background(), time.Duration(runHookTimeout)*time.Minute)
				defer cancel()
				command := exec.CommandContext(ctx, cmdLine)
				command.Dir = hook.ActionPath
				command.Stdin = os.Stdin
				command.Stdout = outFile
				command.Stderr = errFile
				env := jirix.Env()
				command.Env = envvar.MapToSlice(env)
				jirix.Logger.Tracef("Run: %q", cmdLine)
				err = command.Run()
				if ctx.Err() == context.DeadlineExceeded {
					err = ctx.Err()
				}
				scm := gitutil.New(jirix, gitutil.RootDirOpt(filepath.Dir(filepath.Dir(cmdLine))))
				revision, err2 := scm.CurrentRevisionOfBranch("HEAD")
				if err2 == nil {
					jirix.Logger.Debugf("  Invoked hook(%v) for project %q on revision %q", hook.Name, hook.ProjectName, revision)
				}
				return err
			}, fmt.Sprintf("running hook(%s) for project %s", hook.Name, hook.ProjectName),
				retry.AttemptsOpt(jirix.Attempts))
			ch <- result{outFile, errFile, err}
		}(hook)

	}

	err = nil
	timeout := false
	for range hooks {
		out := <-ch
		defer func() {
			if out.outFile != nil {
				out.outFile.Close()
			}
			if out.errFile != nil {
				out.errFile.Close()
			}
		}()
		if out.err == context.DeadlineExceeded {
			timeout = true
			out.outFile.Sync()
			out.outFile.Seek(0, 0)
			var buf bytes.Buffer
			io.Copy(&buf, out.outFile)
			jirix.Logger.Errorf("Timeout while executing hook\n%s\n\n", buf.String())
			err = fmt.Errorf("Hooks execution failed.")
			continue
		}
		var outBuf bytes.Buffer
		if out.outFile != nil {
			out.outFile.Sync()
			out.outFile.Seek(0, 0)
			io.Copy(&outBuf, out.outFile)
		}
		if out.err != nil {
			var buf bytes.Buffer
			if out.errFile != nil {
				out.errFile.Sync()
				out.errFile.Seek(0, 0)
				io.Copy(&buf, out.errFile)
			}
			jirix.Logger.Errorf("%s\n%s\n%s\n", out.err, buf.String(), outBuf.String())
			err = fmt.Errorf("Hooks execution failed.")
		} else {
			if outBuf.String() != "" {
				jirix.Logger.Debugf("%s\n", outBuf.String())
			}
		}
	}
	if timeout {
		err = fmt.Errorf("%s Use %s flag to set timeout.", err, jirix.Color.Yellow("-hook-timeout"))
	}
	return err
}

type commitMsgFetcher map[string][]byte

func (f commitMsgFetcher) fetch(jirix *jiri.X, gerritHost, path string) ([]byte, error) {
	bytes, ok := f[gerritHost]
	if !ok {
		jirix.Logger.Debugf("Fetching %q", gerritHost+"/tools/hooks/commit-msg")
		data, err := gerrit.FetchFile(gerritHost, "/tools/hooks/commit-msg")
		if err != nil {
			if err != gerrit.ErrRedirectOnGerrit {
				// Network or disk IO error, halt jiri
				return nil, err
			}
			// gerritHost require SSO login
			if jirix.RewriteSsoToHttps {
				// Gerrit host require SSO but jiri has rewritesso flag turned on
				// In this case git hooks are useless, stop fetching git hooks
				return nil, errGitHookNotRequired
			}

			// Use commit-msg in cache if the domain has same eTLD and SLD.
			for k, v := range f {
				urlK, err := url.Parse(k)
				if err != nil {
					// This should not happen as this url is already downloaded before.
					return nil, fmt.Errorf("download commit-msg hook for host %q failed due to error %v", gerritHost, err)
				}
				urlG, err := url.Parse(gerritHost)
				if err != nil {
					// This should not happen either as gerritHost will be parsed by gerrit.FetchFile
					return nil, fmt.Errorf("download commit-msg hook from host %q failed due to error %v", gerritHost, err)
				}
				etpoK, err := publicsuffix.EffectiveTLDPlusOne(urlK.Hostname())
				if err != nil {
					// This should not happen as Both SLD and TLD should exist.
					return nil, fmt.Errorf("download commit-msg hook from host %q failed due to error %v", gerritHost, err)
				}
				etpoG, err := publicsuffix.EffectiveTLDPlusOne(urlG.Hostname())
				if err != nil {
					// This should not happen as Both SLD and TLD should exist.
					return nil, fmt.Errorf("download commit-msg hook from host %q failed due to error %v", gerritHost, err)
				}

				if etpoK == etpoG {
					jirix.Logger.Debugf("use commit-msg hook from host %q for host %q due to access limitations", k, gerritHost)
					data = v
					err = nil
					break
				}
			}

			if data == nil {
				// Could not find commit-msg in cache from domains with same eTLD and SLD.
				// Fetch commit-msg from fuchsia's gerrit server.
				data, err = gerrit.FetchFile(fuchsiaGerritHost, "/tools/hooks/commit-msg")
				if err != nil {
					// This will only happen if configuration error occured on fuchsia gerrit server
					return nil, fmt.Errorf("download commit-msg hook from host %q failed due to error %v", fuchsiaGerritHost, err)
				}
				jirix.Logger.Debugf("fallback to commit-msg from host %q for host %q due to access limitations", fuchsiaGerritHost, gerritHost)
			}
		}
		f[gerritHost] = data
		return data, nil
	}
	jirix.Logger.Debugf("Cached %q", gerritHost+"/tools/hooks/commit-msg")
	return bytes, nil
}

func applyGitHooks(jirix *jiri.X, ops []operation) error {
	jirix.TimerPush("apply githooks")
	defer jirix.TimerPop()
	commitMsgFetcher := commitMsgFetcher{}
	for _, op := range ops {
		if op.Kind() != "delete" && !op.Project().LocalConfig.Ignore && !op.Project().LocalConfig.NoUpdate {
			if op.Project().GerritHost != "" {
				hookPath := filepath.Join(op.Project().Path, ".git", "hooks", "commit-msg")
				commitHook, err := os.Create(hookPath)
				if err != nil {
					return fmtError(err)
				}
				bytes, err := commitMsgFetcher.fetch(jirix, op.Project().GerritHost, "/tools/hooks/commit-msg")
				if err != nil {
					if err != errGitHookNotRequired {
						jirix.Logger.Debugf("%v", err)
					}
					commitHook.Close()
					os.Remove(hookPath)
					continue
				}

				if _, err := commitHook.Write(bytes); err != nil {
					return err
				}
				jirix.Logger.Debugf("Saved commit-msg hook to project %q", op.Project().Path)
				commitHook.Close()
				if err := os.Chmod(hookPath, 0750); err != nil {
					return fmtError(err)
				}
			}
			hookPath := filepath.Join(op.Project().Path, ".git", "hooks", "post-commit")
			commitHook, err := os.Create(hookPath)
			if err != nil {
				return err
			}
			bytes := []byte(`#!/bin/sh

if ! git symbolic-ref HEAD &> /dev/null; then
  echo -e "WARNING: You are in a detached head state! You might lose this commit.\nUse 'git checkout -b <branch> to put it on a branch.\n"
fi
`)
			if _, err := commitHook.Write(bytes); err != nil {
				return err
			}
			commitHook.Close()
			if err := os.Chmod(hookPath, 0750); err != nil {
				return err
			}
		}
		if op.Project().GitHooks == "" {
			continue
		}
		// Don't want to run hooks when repo is deleted
		if op.Kind() == "delete" {
			continue
		}
		// Apply git hooks, overwriting any existing hooks.  Jiri is in control of
		// writing all hooks.
		gitHooksDstDir := filepath.Join(op.Project().Path, ".git", "hooks")
		// Copy the specified GitHooks directory into the project's git
		// hook directory.  We walk the file system, creating directories
		// and copying files as we encounter them.
		copyFn := func(path string, info os.FileInfo, err error) error {
			if err != nil {
				return err
			}
			relPath, err := filepath.Rel(op.Project().GitHooks, path)
			if err != nil {
				return err
			}
			dst := filepath.Join(gitHooksDstDir, relPath)
			if info.IsDir() {
				return fmtError(os.MkdirAll(dst, 0755))
			}
			src, err := ioutil.ReadFile(path)
			if err != nil {
				return fmtError(err)
			}
			// The file *must* be executable to be picked up by git.
			return fmtError(ioutil.WriteFile(dst, src, 0755))
		}
		if err := filepath.Walk(op.Project().GitHooks, copyFn); err != nil {
			return err
		}
	}
	return nil
}
