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

import (
	"fmt"
	git2go "github.com/libgit2/git2go"
)

type Git struct {
	rootDir string
}

func NewGit(path string) *Git {
	return &Git{
		rootDir: path,
	}
}

func (g *Git) CurrentRevision() (string, error) {
	repo, err := git2go.OpenRepository(g.rootDir)
	if err != nil {
		return "", err
	}
	defer repo.Free()
	head, err := repo.Head()
	if err != nil {
		return "", err
	}
	defer head.Free()
	return head.Target().String(), nil
}

// Fetch fetches refs and tags from the given remote.
func (g *Git) Fetch(remote string, opts ...FetchOpt) error {
	return g.FetchRefspec(remote, "", opts...)
}

// FetchRefspec fetches refs and tags from the given remote for a particular refspec.
func (g *Git) FetchRefspec(remoteName, refspec string, opts ...FetchOpt) error {
	repo, err := git2go.OpenRepository(g.rootDir)
	if err != nil {
		return err
	}
	defer repo.Free()
	if remoteName == "" {
		return fmt.Errorf("No remote passed")
	}
	remote, err := repo.Remotes.Lookup(remoteName)
	if err != nil {
		return err
	}
	defer remote.Free()
	fetchOptions := &git2go.FetchOptions{}
	tags := false
	prune := false
	for _, opt := range opts {
		switch typedOpt := opt.(type) {
		case TagsOpt:
			tags = bool(typedOpt)
		case PruneOpt:
			prune = bool(typedOpt)
		}
	}
	refspecList := []string{}
	if refspec != "" {
		refspecList = []string{refspec}
	}
	if prune {
		fetchOptions.Prune = git2go.FetchPruneOn
	}
	if tags {
		fetchOptions.DownloadTags = git2go.DownloadTagsAll
	}
	return remote.Fetch(refspecList, fetchOptions, "")
}

func (g *Git) SetRemoteUrl(remote, url string) error {
	repo, err := git2go.OpenRepository(g.rootDir)
	if err != nil {
		return err
	}
	defer repo.Free()
	return repo.Remotes.SetUrl(remote, url)
}

type Reference struct {
	Name     string
	Revision string
	IsHead   bool
}

type Branch struct {
	*Reference
	Tracking *Reference
}

// CurrentRevisionForRef gets current rev for ref/branch/tags
func (g *Git) CurrentRevisionForRef(ref string) (string, error) {
	repo, err := git2go.OpenRepository(g.rootDir)
	if err != nil {
		return "", err
	}
	defer repo.Free()
	if obj, err := repo.RevparseSingle(ref); err != nil {
		return "", err
	} else {
		defer obj.Free()
		if obj.Type() == git2go.ObjectTag {
			tag, err := obj.AsTag()
			if err != nil {
				return "", err
			}
			defer tag.Free()
			return tag.TargetId().String(), nil
		}
		return obj.Id().String(), nil
	}
}

func (g *Git) SetUpstream(branch, upstream string) error {
	repo, err := git2go.OpenRepository(g.rootDir)
	if err != nil {
		return err
	}
	defer repo.Free()
	b, err := repo.LookupBranch(branch, git2go.BranchLocal)
	if err != nil {
		return err
	}
	return b.SetUpstream(upstream)
}

func (g *Git) CreateBranchFromRef(branch, ref string) error {
	repo, err := git2go.OpenRepository(g.rootDir)
	if err != nil {
		return err
	}
	defer repo.Free()
	obj, err := repo.RevparseSingle(ref)
	if err != nil {
		return err
	}
	defer obj.Free()
	c, err := obj.Peel(git2go.ObjectCommit)
	if err != nil {
		return err
	}
	defer c.Free()
	commit, err := c.AsCommit()
	if err != nil {
		return err
	}
	defer commit.Free()
	_, err = repo.CreateBranch(branch, commit, false)
	return err
}

func (g *Git) HasUntrackedFiles() (bool, error) {
	repo, err := git2go.OpenRepository(g.rootDir)
	if err != nil {
		return false, err
	}
	opts := &git2go.StatusOptions{}
	opts.Show = git2go.StatusShowIndexAndWorkdir
	opts.Flags = git2go.StatusOptIncludeUntracked

	statusList, err := repo.StatusList(opts)
	if err != nil {
		return false, err
	}

	defer statusList.Free()
	entryCount, err := statusList.EntryCount()
	if err != nil {
		return false, err
	}
	for i := 0; i < entryCount; i++ {
		entry, err := statusList.ByIndex(i)
		if err != nil {
			return false, err
		}
		if (entry.Status & git2go.StatusWtNew) > 0 {
			return true, nil
		}
	}
	return false, nil
}
func (g *Git) HasUncommittedChanges() (bool, error) {
	repo, err := git2go.OpenRepository(g.rootDir)
	if err != nil {
		return false, err
	}
	opts := &git2go.StatusOptions{}
	opts.Show = git2go.StatusShowIndexAndWorkdir

	statusList, err := repo.StatusList(opts)
	if err != nil {
		return false, err
	}

	defer statusList.Free()
	entryCount, err := statusList.EntryCount()
	if err != nil {
		return false, err
	}
	uncommitedFlag := git2go.StatusWtModified | git2go.StatusWtDeleted |
		git2go.StatusWtTypeChange | git2go.StatusIndexModified |
		git2go.StatusIndexNew | git2go.StatusIndexDeleted |
		git2go.StatusIndexTypeChange | git2go.StatusConflicted

	for i := 0; i < entryCount; i++ {
		entry, err := statusList.ByIndex(i)
		if err != nil {
			return false, err
		}
		if (entry.Status & uncommitedFlag) > 0 {
			return true, nil
		}
	}
	return false, nil
}

// GetBranches returns a slice of the local branches of the current
// repository, followed by the name of the current branch.
func (g *Git) GetBranches() ([]string, string, error) {
	branches, current := []string{}, ""
	repo, err := git2go.OpenRepository(g.rootDir)
	if err != nil {
		return nil, "", err
	}
	defer repo.Free()
	bi, err := repo.NewBranchIterator(git2go.BranchLocal)
	if err != nil {
		return nil, "", err
	}
	err = bi.ForEach(func(b *git2go.Branch, bt git2go.BranchType) error {
		isHead, err := b.IsHead()
		if err != nil {
			return err
		}
		name, err := b.Name()
		if err != nil {
			return err
		}
		branches = append(branches, name)
		if isHead {
			current = name
		}
		return nil
	})
	return branches, current, nil
}

func (g *Git) GetAllBranchesInfo() ([]Branch, error) {
	var branches []Branch
	repo, err := git2go.OpenRepository(g.rootDir)
	if err != nil {
		return nil, err
	}
	defer repo.Free()
	bi, err := repo.NewBranchIterator(git2go.BranchLocal)
	if err != nil {
		return nil, err
	}
	err = bi.ForEach(func(b *git2go.Branch, bt git2go.BranchType) error {
		isHead, err := b.IsHead()
		if err != nil {
			return err
		}
		name, err := b.Name()
		if err != nil {
			return err
		}
		revision := ""
		if t := b.Target(); t != nil {
			revision = t.String()
		}
		branch := Branch{
			&Reference{
				Name:     name,
				Revision: revision,
				IsHead:   isHead,
			}, nil,
		}
		if u, err := b.Upstream(); err != nil && !git2go.IsErrorCode(err, git2go.ErrNotFound) {
			return err
		} else if u != nil {
			defer u.Free()
			branch.Tracking = &Reference{
				Name:     u.Shorthand(),
				Revision: u.Target().String(),
			}
		}
		branches = append(branches, branch)
		return nil
	})
	return branches, err
}
