// 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"
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"strings"

	"go.fuchsia.dev/jiri"
	"go.fuchsia.dev/jiri/gitutil"
)

type importCache struct {
	localManifest bool
	ref           string

	// keeps track of first import tag, this is used to give helpful error
	// message in the case of import conflict
	parentImport string
}

type loader struct {
	Projects         Projects
	ProjectOverrides map[string]Project
	ImportOverrides  map[string]Import
	ProjectLocks     ProjectLocks
	Hooks            Hooks
	Packages         Packages
	PackageLocks     PackageLocks
	TmpDir           string
	localProjects    Projects
	importProjects   Projects
	importCacheMap   map[string]importCache
	importTree       importTree
	update           bool
	cycleStack       []cycleInfo
	manifests        map[string]bool
	lockfiles        map[string]bool
	parentFile       string
}

type importTreeNode struct {
	parents            map[*importTreeNode]bool
	children           map[*importTreeNode]bool
	tag                string
	computedAttributes attributes
}

type importTree struct {
	root          *importTreeNode
	pool          map[string]*importTreeNode
	filenameMap   map[string]bool
	projectKeyMap map[ProjectKey]*importTreeNode
}

func newImportTree() importTree {
	return importTree{
		root: &importTreeNode{
			make(map[*importTreeNode]bool),
			make(map[*importTreeNode]bool),
			"",
			nil,
		},
		pool:          make(map[string]*importTreeNode),
		filenameMap:   make(map[string]bool),
		projectKeyMap: make(map[ProjectKey]*importTreeNode),
	}
}

func (t *importTree) getNode(repoPath, file, ref string) *importTreeNode {
	key := filepath.Join(repoPath, file) + ":" + ref
	if v, ok := t.pool[key]; ok {
		return v
	}
	v := &importTreeNode{
		make(map[*importTreeNode]bool),
		make(map[*importTreeNode]bool),
		key,
		nil,
	}
	if len(t.pool) == 0 {
		t.root.addChild(v)
	}
	t.pool[key] = v
	return v
}

func (t *importTree) buildImportAttributes() {
	// Due to the logic in how remote imports are handled, the
	// manifest loader will create two nodes for a single remote import,
	// causing second one as an orphan. A simple solution is just
	// connect the orphan nodes to the Root to build a connected tree.
	for _, v := range t.pool {
		if len(v.parents) == 0 {
			t.root.addChild(v)
		}
	}
	// The file name of a manifest is used as a git attributes name only if that
	// file name is unique.
	dupMap := make(map[string]bool)
	for k := range t.filenameMap {
		filename := filepath.Base(k)
		if _, ok := dupMap[filename]; ok {
			dupMap[filename] = true
		} else {
			dupMap[filename] = false
		}
	}
	dfsAddAttribute(t.root, newAttributes(""))
	for _, node := range t.pool {
		for attr := range node.computedAttributes {
			if v, ok := dupMap[attr]; ok && v {
				delete(node.computedAttributes, attr)
			}
		}
	}
}

func dfsAddAttribute(curNode *importTreeNode, parentAttrs attributes) {
	if curNode.computedAttributes == nil {
		curNode.computedAttributes = newAttributes(curNode.tag)
	}
	curNode.computedAttributes.Add(parentAttrs)
	for k := range curNode.children {
		dfsAddAttribute(k, curNode.computedAttributes)
	}
}

// (TODO:haowei) generateAttributeGraph generate a graphviz .dot file of
// importTree for debugging purpose. It should be removed once .gitattribute
// generator is considered as stable.
func (t *importTree) generateAttributeGraph() string {
	var buf bytes.Buffer
	buf.WriteString("\ndigraph G {\n")
	nodeCount := 1
	nameMap := make(map[*importTreeNode]string)
	nameMap[t.root] = "n0"
	for _, v := range t.pool {
		nameMap[v] = fmt.Sprintf("n%d", nodeCount)
		nodeCount++
	}

	// The file name of a manifest is used as a git attributes name only if that
	// file name is unique.
	dupMap := make(map[string]bool)
	for k := range t.filenameMap {
		filename := filepath.Base(k)
		if _, ok := dupMap[filename]; ok {
			dupMap[filename] = true
		} else {
			dupMap[filename] = false
		}
	}
	// Output nodes
	for k, v := range nameMap {
		attrs := newAttributes(k.tag)
		for attr := range attrs {
			if v, ok := dupMap[attr]; ok && v {
				delete(attrs, attr)
			}
		}
		buf.WriteString(fmt.Sprintf("\t%s[label=\"%s,%p\"];\n", v, attrs.String(), k))
	}
	buf.WriteString("\n")
	// Output edges
	for k := range nameMap {
		for child := range k.children {
			nameSource := nameMap[k]
			nameTarget, ok := nameMap[child]
			if !ok {
				fmt.Printf("ERROR: cound not find target node %q,%p in nameMap\n", child.tag, child)
				continue
			}
			buf.WriteString(fmt.Sprintf("\t%s -> %s;\n", nameSource, nameTarget))
		}
	}

	buf.WriteString("\n}")
	return buf.String()
}

func (n *importTreeNode) addChild(other *importTreeNode) {
	if other == nil {
		return
	}
	n.children[other] = true
	other.parents[n] = true
}

func (ld *loader) cleanup() {
	if ld.TmpDir != "" {
		os.RemoveAll(ld.TmpDir)
		ld.TmpDir = ""
	}
}

type cycleInfo struct {
	file, key string
}

// newManifestLoader returns a new manifest loader.  The localProjects are used
// to resolve remote imports; if nil, encountering any remote import will result
// in an error.  If update is true, remote manifest import projects that don't
// exist locally are cloned under TmpDir, and inserted into localProjects.
//
// If update is true, remote changes to manifest projects will be fetched, and
// manifest projects that don't exist locally will be created in temporary
// directories, and added to localProjects.
func newManifestLoader(localProjects Projects, update bool, file string) *loader {
	return &loader{
		Projects:         make(Projects),
		ProjectOverrides: make(map[string]Project),
		ImportOverrides:  make(map[string]Import),
		ProjectLocks:     make(ProjectLocks),
		Hooks:            make(Hooks),
		Packages:         make(Packages),
		PackageLocks:     make(PackageLocks),
		localProjects:    localProjects,
		importProjects:   make(Projects),
		update:           update,
		importCacheMap:   make(map[string]importCache),
		manifests:        make(map[string]bool),
		lockfiles:        make(map[string]bool),
		importTree:       newImportTree(),
		parentFile:       file,
	}
}

// loadNoCycles checks for cycles in imports.  There are two types of cycles:
//
//	file - Cycle in the paths of manifest files in the local filesystem.
//	key  - Cycle in the remote manifests specified by remote imports.
//
// Example of file cycles.  File A imports file B, and vice versa.
//
//	file=manifest/A              file=manifest/B
//	<manifest>                   <manifest>
//	  <localimport file="B"/>      <localimport file="A"/>
//	</manifest>                  </manifest>
//
// Example of key cycles.  The key consists of "remote/manifest", e.g.
//
//	https://vanadium.googlesource.com/manifest/v2/default
//
// In the example, key x/A imports y/B, and vice versa.
//
//	key=x/A                               key=y/B
//	<manifest>                            <manifest>
//	  <import remote="y" manifest="B"/>     <import remote="x" manifest="A"/>
//	</manifest>                           </manifest>
//
// The above examples are simple, but the general strategy is demonstrated.  We
// keep a single stack for both files and keys, and push onto each stack before
// running the recursive read or update function, and pop the stack when the
// function is done.  If we see a duplicate on the stack at any point, we know
// there's a cycle.  Note that we know the file for both local and remote
// imports, but we only know the key for remote imports; the key for local
// imports is empty.
//
// A more complex case would involve a combination of local and remote imports,
// using the "root" attribute to change paths on the local filesystem.  In this
// case the key will eventually expose the cycle.
func (ld *loader) loadNoCycles(jirix *jiri.X, root, repoPath, file, ref, cycleKey, parentImport string, localManifest bool) error {
	f := file
	if repoPath != "" {
		f = filepath.Join(repoPath, file)
	}
	info := cycleInfo{f, cycleKey}
	for _, c := range ld.cycleStack {
		switch {
		case f == c.file:
			return fmt.Errorf("import cycle detected in local manifest files: %q", append(ld.cycleStack, info))
		case cycleKey == c.key && cycleKey != "":
			return fmt.Errorf("import cycle detected in remote manifest imports: %q", append(ld.cycleStack, info))
		}
	}
	ld.cycleStack = append(ld.cycleStack, info)
	if err := ld.load(jirix, root, repoPath, file, ref, parentImport, localManifest); err != nil {
		return err
	}
	ld.cycleStack = ld.cycleStack[:len(ld.cycleStack)-1]
	return nil
}

// shortFileName returns the relative path if file is relative to root,
// otherwise returns the file name unchanged.
func shortFileName(root, repoPath, file, ref string) string {
	if repoPath != "" {
		return fmt.Sprintf("%s %s:%s", shortFileName(root, "", repoPath, ""), ref, file)
	}
	if p := root + string(filepath.Separator); strings.HasPrefix(file, p) {
		return file[len(p):]
	}
	return file
}

func (ld *loader) Load(jirix *jiri.X, root, repoPath, file, ref, cycleKey, parentImport string, localManifest bool) error {
	jirix.TimerPush("load " + shortFileName(jirix.Root, repoPath, file, ref))
	defer jirix.TimerPop()
	return ld.loadNoCycles(jirix, root, repoPath, file, ref, cycleKey, parentImport, localManifest)
}

func (ld *loader) cloneManifestRepo(jirix *jiri.X, remote *Import, cacheDirPath string, localManifest bool) error {
	if !ld.update || localManifest {
		jirix.Logger.Warningf("import %q not found locally, getting from server. Please check your manifest file (default: .jiri_manifest).\nMake sure that the 'name' attributes on the 'import' and 'project' tags match and that there is a corresponding 'project' tag for every 'import' tag.\n\n", remote.Name)
	}
	jirix.Logger.Debugf("clone manifest project %q", remote.Name)
	// The remote manifest project doesn't exist locally.  Clone it into a
	// temp directory, and add it to ld.localProjects.
	if ld.TmpDir == "" {
		var err error
		if ld.TmpDir, err = os.MkdirTemp("", "jiri-load"); err != nil {
			return fmt.Errorf("TempDir() failed: %v", err)
		}
	}
	path := filepath.Join(ld.TmpDir, remote.projectKeyFileName())
	p, err := remote.toProject(path)
	if err != nil {
		return err
	}
	if err := os.MkdirAll(path, 0755); err != nil {
		return fmtError(err)
	}
	remoteUrl := rewriteRemote(jirix, p.Remote)
	task := jirix.Logger.AddTaskMsg("Creating manifest: %s", remote.Name)
	defer task.Done()
	if cacheDirPath != "" {
		logStr := fmt.Sprintf("update/create cache for project %q", remote.Name)
		jirix.Logger.Debugf(logStr)
		task := jirix.Logger.AddTaskMsg(logStr)
		defer task.Done()
		if err := updateOrCreateCache(jirix, cacheDirPath, remoteUrl, remote.RemoteBranch, remote.Revision, 0, (p.GitSubmodules && jirix.EnableSubmodules)); err != nil {
			return err
		}
	}
	opts := []gitutil.CloneOpt{gitutil.ReferenceOpt(cacheDirPath), gitutil.NoCheckoutOpt(true)}
	if jirix.UsePartialClone(p.Remote) {
		opts = append(opts, gitutil.OmitBlobsOpt(true))
	}
	if jirix.Dissociate {
		opts = append(opts, gitutil.DissociateOpt(true))
	}
	if err := clone(jirix, remoteUrl, path, opts...); err != nil {
		return err
	}
	scm := gitutil.New(jirix, gitutil.RootDirOpt(p.Path))
	if jirix.UsePartialClone(p.Remote) && cacheDirPath != "" {
		// Set Cache Remote
		if err := scm.Config("extensions.partialClone", "origin"); err != nil {
			return err
		}
		if err := scm.AddOrReplacePartialRemote("cache", cacheDirPath); err != nil {
			return err
		}
	}

	p.Revision = remote.Revision
	p.RemoteBranch = remote.RemoteBranch
	if err := checkoutHeadRevision(jirix, p, false, false); err != nil {
		return fmt.Errorf("Not able to checkout head for %s(%s): %v", p.Name, p.Path, err)
	}
	ld.localProjects[remote.ProjectKey()] = p
	return nil
}

// loadLockFile will recursively load lockfiles from dir to its parent directories until it
// reaches $JIRI_ROOT. It will only report errors on lockfiles such as unknown format or confliting data.
// All I/O related errors will be ignored.
func (ld *loader) loadLockFile(jirix *jiri.X, repoPath, dir, lockFileName, ref string) error {
	lockfile := filepath.Join(dir, lockFileName)
	lockKey := lockfile
	if repoPath != "" {
		lockKey = filepath.Join(repoPath, lockfile) + ":" + ref
	}
	if ld.lockfiles[lockKey] {
		return nil
	}

	if !(dir == "" || dir == "." || dir == jirix.Root || dir == string(filepath.Separator)) {
		if err := ld.loadLockFile(jirix, repoPath, filepath.Dir(dir), lockFileName, ref); err != nil {
			return err
		}
	}

	var data []byte
	if repoPath != "" {
		s, err := gitutil.New(jirix, gitutil.RootDirOpt(repoPath)).Show(ref, lockfile)
		if err != nil {
			// It's fine if jiri.lock cannot be find, skip this jiri.lock
			jirix.Logger.Debugf("Could not find %q in repository %q for ref %q", lockfile, repoPath, ref)
			return nil
		}
		data = []byte(s)
	} else {
		if _, err := os.Stat(lockfile); err != nil {
			if os.IsNotExist(err) {
				jirix.Logger.Debugf("could not find %q file at %q", lockFileName, lockfile)
			} else {
				jirix.Logger.Debugf("could not access %q file at %q due to error %v", lockFileName, lockfile, err)
			}
			return nil
		}
		temp, err := os.ReadFile(lockfile)
		if err != nil {
			// Supress I/O errors as it is OK if a lockfile cannot be accessed.
			return nil
		}
		data = temp
	}
	if err := ld.parseLockData(jirix, data); err != nil {
		return err
	}
	if repoPath == "" {
		jirix.Logger.Debugf("loaded lockfile at %s", lockfile)
	} else {
		jirix.Logger.Debugf("loaded lockfile at %q in repository %q for ref %q", lockfile, repoPath, ref)
	}
	ld.lockfiles[lockKey] = true
	return nil
}

func (ld *loader) parseLockData(jirix *jiri.X, data []byte) error {
	projectLocks, pkgLocks, err := UnmarshalLockEntries(data)
	if err != nil {
		return err
	}

	for k, v := range projectLocks {
		if projLock, ok := ld.ProjectLocks[k]; ok {
			if projLock != v && !jirix.UsingImportOverride {
				return fmt.Errorf("conflicting project lock entries %+v with %+v", projLock, v)
			}
		} else {
			ld.ProjectLocks[k] = v
		}
	}

	for k, v := range pkgLocks {
		if pkgLock, ok := ld.PackageLocks[k]; ok {
			// Only package locks may conflict during a normal 'jiri resolve'.
			// Treating conflicts as errors in all other scenarios.
			if !pkgLock.LockEqual(v) && !jirix.IgnoreLockConflicts && !jirix.UsingImportOverride {
				return fmt.Errorf("conflicting package lock entries %+v with %+v", pkgLock, v)
			}
		} else {
			ld.PackageLocks[k] = v
		}
	}

	return nil
}

func (ld *loader) load(jirix *jiri.X, root, repoPath, file, ref, parentImport string, localManifest bool) error {
	f := file
	if repoPath != "" {
		f = filepath.Join(repoPath, file)
	}
	if ld.manifests[f] {
		return nil
	}
	ld.manifests[f] = true

	loadManifestAndLocks := func(jirix *jiri.X, file string) (*Manifest, error) {
		if repoPath == "" {
			m, err := ManifestFromFile(jirix, file)
			if err != nil {
				return nil, fmt.Errorf("Error reading from manifest file %s %s:%s:error(%s)", repoPath, ref, file, err)
			}
			if jirix.LockfileEnabled {
				if err := ld.loadLockFile(jirix, repoPath, filepath.Dir(file), jirix.LockfileName, ref); err != nil {
					return nil, err
				}
			}
			return m, err
		}
		// repoPath != ""
		s, err := gitutil.New(jirix, gitutil.RootDirOpt(repoPath)).Show(ref, file)
		if err != nil {
			return nil, fmt.Errorf("Unable to get manifest file for %s %s:%s:error(%s)", repoPath, ref, file, err)
		}
		m, err := ManifestFromBytes([]byte(s))
		if err != nil {
			return nil, fmt.Errorf("Error reading from manifest file %s %s:%s:error(%s)", repoPath, ref, file, err)
		}
		if jirix.LockfileEnabled {
			if err := ld.loadLockFile(jirix, repoPath, filepath.Dir(file), jirix.LockfileName, ref); err != nil {
				return nil, err
			}
		}
		return m, nil
	}

	m, err := loadManifestAndLocks(jirix, file)
	if err != nil {
		return err
	}

	if jirix.UsingSnapshot && !jirix.OverrideOptional {
		// using attributes defined in snapshot file instead of
		// using predefined ones in jiri init.
		jirix.FetchingAttrs = m.Attributes
	}

	// Add override information
	if parentImport == "" {
		for _, p := range m.ProjectOverrides {
			// Reuse the MakeProjectKey function in case it is changed
			// in the future.
			key := p.Key().String()
			ld.ProjectOverrides[key] = p
		}
		for _, p := range m.ImportOverrides {
			// Reuse the MakeProjectKey function in case it is changed
			// in the future.
			key := p.ProjectKey().String()
			if !jirix.UsingImportOverride {
				jirix.UsingImportOverride = true
			}
			ld.ImportOverrides[key] = p
		}
	} else if len(m.ProjectOverrides)+len(m.ImportOverrides) > 0 {
		return fmt.Errorf("manifest %q contains overrides but was imported by %q. Overrides are allowed only in the root manifest", shortFileName(jirix.Root, repoPath, file, ref), parentImport)
	}

	// Use manifest's directory name and file name as default
	// git attributes. It will be later expanded using the
	// import relationships.
	defaultGitAttrs := func() string {
		manifestFile := file
		if repoPath != "" {
			manifestFile = filepath.Join(repoPath, manifestFile)
		}
		containingDir := filepath.Base(filepath.Dir(manifestFile))
		filename := file
		ld.importTree.filenameMap[filename] = false
		return containingDir + "," + filepath.Base(file)
	}
	self := ld.importTree.getNode(repoPath, file, ref)
	self.tag = defaultGitAttrs()
	// Process remote imports.
	for _, remote := range m.Imports {
		// Apply override if it exists.
		remote, err := overrideImport(remote, ld.ProjectOverrides, ld.ImportOverrides)
		if err != nil {
			return err
		}
		nextRoot := filepath.Join(root, remote.Root)
		remote.Name = filepath.Join(nextRoot, remote.Name)
		key := remote.ProjectKey()
		p, ok := ld.localProjects[key]
		cacheDirPath, err := cacheDirPathFromRemote(jirix, remote.Remote)
		if err != nil {
			return err
		}

		if !ok {
			if err := ld.cloneManifestRepo(jirix, &remote, cacheDirPath, localManifest); err != nil {
				return err
			}
			p = ld.localProjects[key]
		}
		// Reset the project to its specified branch and load the next file.  Note
		// that we call load() recursively, so multiple files may be loaded by
		// loadImport.
		p.Revision = remote.Revision
		p.RemoteBranch = remote.RemoteBranch
		ld.importProjects[key] = p
		pi := parentImport
		if pi == "" {
			pi = fmt.Sprintf("import[manifest=%q, remote=%q]", remote.Manifest, remote.Remote)
		}

		self.addChild(ld.importTree.getNode(repoPath, remote.Manifest, ""))
		if err := ld.loadImport(jirix, nextRoot, remote.Manifest, remote.cycleKey(), cacheDirPath, pi, p, localManifest); err != nil {
			return err
		}
	}

	// Process local imports.
	for _, local := range m.LocalImports {
		nextFile := filepath.Join(filepath.Dir(file), local.File)
		self.addChild(ld.importTree.getNode(repoPath, nextFile, ref))
		if err := ld.Load(jirix, root, repoPath, nextFile, ref, "", parentImport, localManifest); err != nil {
			return err
		}
	}

	hookMap := make(map[string][]*Hook)

	for idx := range m.Hooks {
		hook := &m.Hooks[idx]
		if err := hook.validate(); err != nil {
			return err
		}
		hookMap[hook.ProjectName] = append(hookMap[hook.ProjectName], hook)
	}

	// Collect projects.
	for _, project := range m.Projects {
		// Apply override if it exists.
		project, err := overrideProject(project, ld.ProjectOverrides, ld.ImportOverrides)
		if err != nil {
			return err
		}
		// normalize project attributes
		project.ComputedAttributes = newAttributes(project.Attributes)
		project.Attributes = project.ComputedAttributes.String()
		// Make paths absolute by prepending <root>.
		project.absolutizePaths(filepath.Join(jirix.Root, root))

		if hooks, ok := hookMap[project.Name]; ok {
			for _, hook := range hooks {
				hook.ActionPath = project.Path
			}
		}

		// Prepend the root to the project name.  This will be a noop if the import is not rooted.
		project.Name = filepath.Join(root, project.Name)
		key := project.Key()

		if r, ok := ld.importProjects[key]; ok {
			// update revision for this project
			if r.Revision != "" && r.Revision != "HEAD" {
				if project.Revision == "" || project.Revision == "HEAD" {
					project.Revision = r.Revision
				} else if r.Revision != project.Revision {
					return fmt.Errorf("project %q found in %q defines different revision than its corresponding import tag.", key, shortFileName(jirix.Root, repoPath, file, ref))
				}
			}
		}

		if dup, ok := ld.Projects[key]; ok && !reflect.DeepEqual(dup, project) {
			// TODO(toddw): Tell the user the other conflicting file.
			return fmt.Errorf("duplicate project %q found in %q", key, shortFileName(jirix.Root, repoPath, file, ref))
		}

		// Record manifest location.
		project.ManifestPath = f

		// Associate project with importTreeNode for git attributes propagation.
		ld.importTree.projectKeyMap[key] = self

		ld.Projects[key] = project
	}

	for _, hook := range m.Hooks {
		if hook.ActionPath == "" {
			return fmt.Errorf("invalid hook %q for project %q. Please make sure you are importing project %q and this hook is in the manifest which directly/indirectly imports that project.", hook.Name, hook.ProjectName, hook.ProjectName)
		}
		key := hook.Key()
		ld.Hooks[key] = hook
	}

	for _, pkg := range m.Packages {
		// normalize package attributes.
		pkg.ComputedAttributes = newAttributes(pkg.Attributes)
		pkg.Attributes = pkg.ComputedAttributes.String()
		// Record manifest location.
		pkg.ManifestPath = f
		key := pkg.Key()
		if val, ok := ld.Packages[key]; ok {
			// Package with same remote url and local path already exists in manifest.
			// Abort loading.
			return fmt.Errorf("conflicting packages: %v conflicts %v when loading manifest %s", val, pkg, file)
		}
		ld.Packages[key] = pkg
	}
	return nil
}

func (ld *loader) loadImport(jirix *jiri.X, root, file, cycleKey, cacheDirPath, parentImport string, project Project, localManifest bool) (e error) {
	lm := localManifest
	ref := ""

	if v, ok := ld.importCacheMap[strings.Trim(project.Remote, "/")]; ok {
		// local manifest in cache takes precedence as this might be manifest mentioned in .jiri_manifest
		lm = v.localManifest
		ref = v.ref
		// check conflicting imports
		if !lm && ref != "JIRI_HEAD" {
			if tref, err := GetHeadRevision(project); err != nil {
				return err
			} else if tref != ref {
				return fmt.Errorf("Conflicting ref for import %s - %q and %q. There are conflicting imports in file:\n%s:\n'%s' and '%s'",
					jirix.Color.Red(project.Remote), ref, tref, jirix.Color.Yellow(ld.parentFile),
					jirix.Color.Yellow(v.parentImport), jirix.Color.Yellow(parentImport))
			}
		}
	} else {
		// We don't need to fetch or find ref for local manifest changes
		if !lm {
			// We only fetch on updates.
			if ld.update {
				// Fetch only if project not pinned or revision not available in
				// local git as we anyways update all the projects later.
				fetch := true
				if project.Revision != "" && project.Revision != "HEAD" {
					if _, err := gitutil.New(jirix, gitutil.RootDirOpt(project.Path)).Show(project.Revision, ""); err == nil {
						fetch = false
					}
				}
				if fetch {
					if cacheDirPath != "" {
						remoteUrl := rewriteRemote(jirix, project.Remote)
						if err := updateOrCreateCache(jirix, cacheDirPath, remoteUrl, project.RemoteBranch, project.Revision, 0, (project.GitSubmodules && jirix.EnableSubmodules)); err != nil {
							return err
						}
					}
					if err := fetchAll(jirix, project); err != nil {
						return fmt.Errorf("Fetch failed for project(%s), %s", project.Path, err)
					}
				}
			} else {
				// If not updating then try to get file from JIRI_HEAD
				if _, err := gitutil.New(jirix, gitutil.RootDirOpt(project.Path)).Show("JIRI_HEAD", ""); err == nil {
					// JIRI_HEAD available, set ref
					ref = "JIRI_HEAD"
				}
			}
			if ref == "" {
				var err error
				if ref, err = GetHeadRevision(project); err != nil {
					return err
				}
			}
		}
		ld.importCacheMap[strings.Trim(project.Remote, "/")] = importCache{
			localManifest: lm,
			ref:           ref,
			parentImport:  parentImport,
		}
	}
	if lm {
		// load from local checked out file
		return ld.Load(jirix, root, "", filepath.Join(project.Path, file), "", cycleKey, parentImport, false)
	}
	return ld.Load(jirix, root, project.Path, file, ref, cycleKey, parentImport, false)
}

func (ld *loader) GenerateGitAttributesForProjects(jirix *jiri.X) {
	ld.importTree.buildImportAttributes()
	for k, v := range ld.Projects {
		if treeNode, ok := ld.importTree.projectKeyMap[k]; ok {
			v.GitAttributes = treeNode.computedAttributes.String()
			ld.Projects[k] = v
		}
	}
	jirix.Logger.Debugf("Generated dot file: %s", ld.importTree.generateAttributeGraph())
}
