package ghpkg

import (
	"fmt"

	"github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/plumbing/object"
)

type GitTool struct {
	repoURL  string
	repoPath string
	*git.Repository
}

func NewGitTool(repoURL, repoPath string) (*GitTool, error) {
	repo, err := git.PlainOpen(repoPath)
	if err != nil {
		return nil, err
	}
	return &GitTool{repoURL: repoURL, repoPath: repoPath, Repository: repo}, nil
}

func (g *GitTool) GetRepoURL() string {
	return g.repoURL
}

func (g *GitTool) GetBranch() (string, error) {
	h, err := g.Head()
	if err != nil {
		return "", err
	}
	// if checking a PR
	if h.Name() == "HEAD" {
		return "pr", nil
	}

	branch := string(h.Name()[len("refs/heads/"):])

	if branch == "" {
		return "", fmt.Errorf("%s isn't a git repo", g.repoPath)
	}
	return branch, nil
}

func (g *GitTool) GetCommit() (string, error) {
	h, err := g.Head()
	if err != nil {
		return "", err
	}
	hash := h.Hash()
	if hash.IsZero() {
		return "", fmt.Errorf("cannot get the commit hash")
	}
	return hash.String()[:7], nil
}

func (g *GitTool) GetCommitTs() (int64, error) {
	h, err := g.Head()
	if err != nil {
		return 0, err
	}
	cIter, err := g.Log(&git.LogOptions{From: h.Hash(), Order: git.LogOrderCommitterTime})
	if err != nil {
		return 0, err
	}
	var commitTs int64
	cIter.ForEach(func(commit *object.Commit) error {
		if commit.Hash == h.Hash() {
			commitTs = commit.Author.When.UnixNano()
		}
		return nil
	})
	if commitTs == 0 {
		return 0, fmt.Errorf("cannot get commit ts")
	}
	return commitTs, nil
}
