package tools

import (
	"github.com/go-git/go-git/v6"
	"github.com/go-git/go-git/v6/plumbing"
	"github.com/go-git/go-git/v6/plumbing/object"
	"github.com/go-git/go-git/v6/plumbing/transport/http"
)

func Git() *g {
	return &g{}
}

type (
	g struct {
		user  string
		email string
		token string
	}
)

func (t *g) User(user string) *g {
	t.user = user
	return t
}

func (t *g) Email(email string) *g {
	t.email = email
	return t
}

func (t *g) Token(token string) *g {
	t.token = token
	return t
}

func (t *g) Clone(repo, ref, path string) error {
	_, err := git.PlainClone(
		path,
		&git.CloneOptions{
			URL:           repo,
			ReferenceName: plumbing.ReferenceName(ref),
			Auth: &http.BasicAuth{
				Username: t.user,
				Password: t.token,
			},
		})

	return err
}

func (t *g) Add(repo, file string) error {
	r, err := git.PlainOpen(repo)
	if err != nil {
		return err
	}

	w, err := r.Worktree()
	if err != nil {
		return err
	}

	_, err = w.Add(file)
	if err != nil {
		return err
	}

	return err
}

func (t *g) Commit(repo, message string) error {
	r, err := git.PlainOpen(repo)
	if err != nil {
		return err
	}

	w, err := r.Worktree()
	if err != nil {
		return err
	}

	_, err = w.Commit(message, &git.CommitOptions{
		Author: &object.Signature{
			Name:  t.user,
			Email: t.email,
		},
	})
	if err != nil {
		return err
	}

	return err
}

func (t *g) Push(repo string) error {
	r, err := git.PlainOpen(repo)
	if err != nil {
		return err
	}

	err = r.Push(&git.PushOptions{
		Auth: &http.BasicAuth{
			Username: t.user,
			Password: t.token,
		},
	})
	if err != nil {
		return err
	}

	return err
}
