// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package gitindex

import (
	"fmt"
	"log"
	"net/url"
	"path"
	"path/filepath"
	"strings"

	git "github.com/libgit2/git2go"
)

// repoWalker walks a tree, recursing into submodules.
type repoWalker struct {
	repo *git.Repository

	repoURL *url.URL
	tree    map[FileKey]BlobLocation

	// Path => SubmoduleEntry
	submodules map[string]*SubmoduleEntry

	// Path => commit SHA1
	subRepoVersions map[string]git.Oid
	err             error
	repoCache       *RepoCache

	// If set, don't gasp on missing submodules.
	ignoreMissingSubmodules bool
}

// subURL returns the URL for a submodule.
func (w *repoWalker) subURL(relURL string) (*url.URL, error) {
	if w.repoURL == nil {
		return nil, fmt.Errorf("no URL for base repo.")
	}
	if strings.HasPrefix(relURL, "../") {
		u := *w.repoURL
		u.Path = path.Join(u.Path, relURL)
		return &u, nil
	}

	return url.Parse(relURL)
}

// newRepoWalker creates a new repoWalker.
func newRepoWalker(r *git.Repository, repoURL string, repoCache *RepoCache) *repoWalker {
	u, _ := url.Parse(repoURL)
	return &repoWalker{
		repo:                    r,
		repoURL:                 u,
		tree:                    map[FileKey]BlobLocation{},
		repoCache:               repoCache,
		subRepoVersions:         map[string]git.Oid{},
		ignoreMissingSubmodules: true,
	}
}

// parseModuleMap initializes rw.submodules.
func (rw *repoWalker) parseModuleMap(t *git.Tree) error {
	modEntry := t.EntryByName(".gitmodules")
	if modEntry != nil {
		blob, err := rw.repo.LookupBlob(modEntry.Id)
		if err != nil {
			return err
		}

		mods, err := ParseGitModules(blob.Contents())
		if err != nil {
			return err
		}
		rw.submodules = map[string]*SubmoduleEntry{}
		for _, entry := range mods {
			rw.submodules[entry.Path] = entry
		}
	}
	return nil
}

// TreeToFiles fetches the blob SHA1s for a tree. If repoCache is
// non-nil, recurse into submodules. In addition, it returns a mapping
// that indicates in which repo each SHA1 can be found.
func TreeToFiles(r *git.Repository, t *git.Tree,
	repoURL string, repoCache *RepoCache) (map[FileKey]BlobLocation, map[string]git.Oid, error) {
	ref := newRepoWalker(r, repoURL, repoCache)

	if err := ref.parseModuleMap(t); err != nil {
		return nil, nil, err
	}

	t.Walk(ref.cbInt)
	if ref.err != nil {
		return nil, nil, ref.err
	}
	return ref.tree, ref.subRepoVersions, nil
}

func (r *repoWalker) tryHandleSubmodule(p string, id *git.Oid) error {
	err := r.handleSubmodule(p, id)
	if r.ignoreMissingSubmodules && err != nil {
		log.Printf("submodule %s: ignoring error %v", p, err)
		err = nil
	}

	return nil
}

func (r *repoWalker) handleSubmodule(p string, id *git.Oid) error {
	submod := r.submodules[p]
	if submod == nil {
		return fmt.Errorf("no entry for submodule path %q", r.repoURL)
	}

	subURL, err := r.subURL(submod.URL)
	if err != nil {
		return err
	}

	subRepo, err := r.repoCache.Open(subURL)
	if err != nil {
		return err
	}

	obj, err := subRepo.Lookup(id)
	if err != nil {
		return err
	}
	defer obj.Free()

	r.subRepoVersions[p] = *id
	treeObj, err := obj.Peel(git.ObjectTree)
	if err != nil {
		return err
	}
	if treeObj != obj {
		defer treeObj.Free()
	}
	tree, err := treeObj.AsTree()
	if err != nil {
		return err
	}
	subTree, subVersions, err := TreeToFiles(subRepo, tree, subURL.String(), r.repoCache)
	if err != nil {
		return err
	}
	for k, repo := range subTree {
		r.tree[FileKey{
			SubRepoPath: filepath.Join(p, k.SubRepoPath),
			Path:        k.Path,
			ID:          k.ID,
		}] = repo
	}
	for k, v := range subVersions {
		r.subRepoVersions[filepath.Join(p, k)] = v
	}
	return nil
}

// cb is the git2go callback
func (r *repoWalker) cb(n string, e *git.TreeEntry) error {
	p := filepath.Join(n, e.Name)
	if e.Type == git.ObjectCommit && r.repoCache != nil {
		if err := r.tryHandleSubmodule(p, e.Id); err != nil {
			return fmt.Errorf("submodule %s: %v", p, err)
		}
	}

	switch e.Filemode {
	case git.FilemodeBlob, git.FilemodeBlobExecutable:
	default:
		return nil
	}

	if e.Type != git.ObjectBlob {
		return nil
	}
	r.tree[FileKey{
		Path: p,
		ID:   *e.Id,
	}] = BlobLocation{
		Repo: r.repo,
		URL:  r.repoURL,
	}
	return nil
}

// cbInt is the callback suitable for use with git2go.
func (r *repoWalker) cbInt(n string, e *git.TreeEntry) int {
	err := r.cb(n, e)
	if err != nil {
		r.err = err
		return 1
	}
	return 0
}

// FileKey describes a blob at a location in the final tree. We also
// record the subrepository from where it came.
type FileKey struct {
	SubRepoPath string
	Path        string
	ID          git.Oid
}

func (k *FileKey) FullPath() string {
	return filepath.Join(k.SubRepoPath, k.Path)
}

// BlobLocation holds data where a blob can be found.
type BlobLocation struct {
	Repo *git.Repository
	URL  *url.URL
}

func (l *BlobLocation) Blob(id *git.Oid) ([]byte, error) {
	blob, err := l.Repo.LookupBlob(id)
	if err != nil {
		return nil, err
	}
	defer blob.Free()
	return blob.Contents(), nil
}
