package git

import (
	"os"
	"strings"

	"coopcloud.tech/abra/pkg/log"
	"github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/plumbing"
)

// gitCloneIgnoreErr checks whether we can ignore a git clone error or not.
func gitCloneIgnoreErr(err error) bool {
	if strings.Contains(err.Error(), "authentication required") {
		return true
	}

	if strings.Contains(err.Error(), "remote repository is empty") {
		return true
	}

	return false
}

// Clone runs a git clone which accounts for different default branches.
func Clone(dir, url string) error {
	if _, err := os.Stat(dir); os.IsNotExist(err) {
		log.Debugf("git clone: %s", dir, url)

		_, err := git.PlainClone(dir, false, &git.CloneOptions{
			URL:           url,
			Tags:          git.AllTags,
			ReferenceName: plumbing.ReferenceName("refs/heads/main"),
			SingleBranch:  true,
		})

		if err != nil && gitCloneIgnoreErr(err) {
			log.Debugf("git clone: %s cloned successfully", dir)
			return nil
		}

		if err != nil {
			log.Debug("git clone: main branch failed, attempting master branch")

			_, err := git.PlainClone(dir, false, &git.CloneOptions{
				URL:           url,
				Tags:          git.AllTags,
				ReferenceName: plumbing.ReferenceName("refs/heads/master"),
				SingleBranch:  true,
			})

			if err != nil && gitCloneIgnoreErr(err) {
				log.Debugf("git clone: %s cloned successfully", dir)
				return nil
			}

			if err != nil {
				return err
			}
		}

		log.Debugf("git clone: %s cloned successfully", dir)
	} else {
		log.Debugf("git clone: %s already exists", dir)
	}

	return nil
}
