// Copyright 2022 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Package git provides helpers for interfacing with the git tool
package git

import (
	"context"
	"encoding/hex"
	"errors"
	"fmt"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

// Hash is a 20 byte, git object hash.
type Hash [20]byte

func (h Hash) String() string { return hex.EncodeToString(h[:]) }

// IsZero returns true if the hash h is all zeros
func (h Hash) IsZero() bool {
	zero := Hash{}
	return h == zero
}

// ParseHash returns a Hash from a hexadecimal string.
func ParseHash(s string) (Hash, error) {
	b, err := hex.DecodeString(s)
	if err != nil {
		return Hash{}, fmt.Errorf("failed to parse hash '%v':\n  %w", s, err)
	}
	h := Hash{}
	copy(h[:], b)
	return h, nil
}

// The timeout for git operations if no other timeout is specified
var DefaultTimeout = time.Minute

// Git wraps the 'git' executable
type Git struct {
	// Path to the git executable
	exe string
	// Debug flag to print all command to the `git` executable
	LogAllActions bool
}

// New returns a new Git instance
func New(exe string) (*Git, error) {
	if exe == "" {
		g, err := exec.LookPath("git")
		if err != nil {
			return nil, fmt.Errorf("failed to find git: %v", err)
		}
		exe = g
	}
	if _, err := os.Stat(exe); err != nil {
		return nil, err
	}
	return &Git{exe: exe}, nil
}

// Credentials holds the user name and password used to perform git operations.
type Credentials struct {
	Username string
	Password string
}

// Empty return true if there's no username or password for authentication
func (a Credentials) Empty() bool {
	return a.Username == "" && a.Password == ""
}

// addToURL returns the url with the credentials appended
func (c Credentials) addToURL(u string) (string, error) {
	if !c.Empty() {
		modified, err := url.Parse(u)
		if err != nil {
			return "", fmt.Errorf("failed to parse url '%v': %v", u, err)
		}
		modified.User = url.UserPassword(c.Username, c.Password)
		u = modified.String()
	}
	return u, nil
}

// ErrRepositoryDoesNotExist indicates that a repository does not exist
var ErrRepositoryDoesNotExist = errors.New("repository does not exist")

// Open opens an existing git repo at path. If the repository does not exist at
// path then ErrRepositoryDoesNotExist is returned.
func (g Git) Open(path string) (*Repository, error) {
	info, err := os.Stat(filepath.Join(path, ".git"))
	if err != nil || !info.IsDir() {
		return nil, ErrRepositoryDoesNotExist
	}
	return &Repository{g, path}, nil
}

// Optional settings for Git.Clone
type CloneOptions struct {
	// If specified then the given branch will be cloned instead of the default
	Branch string
	// Timeout for the operation
	Timeout time.Duration
	// Authentication for the clone
	Credentials Credentials
}

// Clone performs a clone of the repository at url to path.
func (g Git) Clone(path, url string, opt *CloneOptions) (*Repository, error) {
	if err := os.MkdirAll(path, 0777); err != nil {
		return nil, err
	}
	if opt == nil {
		opt = &CloneOptions{}
	}
	url, err := opt.Credentials.addToURL(url)
	if err != nil {
		return nil, err
	}
	r := &Repository{g, path}
	args := []string{"clone", url, "."}
	if opt.Branch != "" {
		args = append(args, "--branch", opt.Branch)
	}
	if _, err := r.run(nil, opt.Timeout, args...); err != nil {
		return nil, err
	}
	return r, nil
}

// Repository points to a git repository
type Repository struct {
	// Path to the 'git' executable
	Git Git
	// Repo directory
	Path string
}

// Optional settings for Repository.Fetch
type FetchOptions struct {
	// The remote name. Defaults to 'origin'
	Remote string
	// Timeout for the operation
	Timeout time.Duration
	// Git authentication for the remote
	Credentials Credentials
}

// Fetch performs a fetch of a reference from the remote, returning the Hash of
// the fetched reference.
func (r Repository) Fetch(ref string, opt *FetchOptions) (Hash, error) {
	if opt == nil {
		opt = &FetchOptions{}
	}
	if opt.Remote == "" {
		opt.Remote = "origin"
	}
	if _, err := r.run(nil, opt.Timeout, "fetch", opt.Remote, ref); err != nil {
		return Hash{}, err
	}
	out, err := r.run(nil, 0, "rev-parse", "FETCH_HEAD")
	if err != nil {
		return Hash{}, err
	}
	return ParseHash(out)
}

// Optional settings for Repository.Push
type PushOptions struct {
	// The remote name. Defaults to 'origin'
	Remote string
	// Timeout for the operation
	Timeout time.Duration
	// Git authentication for the remote
	Credentials Credentials
}

// Push performs a push of the local reference to the remote reference.
func (r Repository) Push(localRef, remoteRef string, opt *PushOptions) error {
	if opt == nil {
		opt = &PushOptions{}
	}
	if opt.Remote == "" {
		opt.Remote = "origin"
	}
	url, err := r.run(nil, opt.Timeout, "remote", "get-url", opt.Remote)
	if err != nil {
		return err
	}
	url, err = opt.Credentials.addToURL(url)
	if err != nil {
		return err
	}
	if _, err := r.run(nil, opt.Timeout, "push", url, localRef+":"+remoteRef); err != nil {
		return err
	}
	return nil
}

// Optional settings for Repository.Add
type AddOptions struct {
	// Timeout for the operation
	Timeout time.Duration
	// Git authentication for the remote
	Credentials Credentials
}

// Add stages the listed files
func (r Repository) Add(path string, opt *AddOptions) error {
	if opt == nil {
		opt = &AddOptions{}
	}
	if _, err := r.run(nil, opt.Timeout, "add", path); err != nil {
		return err
	}
	return nil
}

// Optional settings for Repository.Commit
type CommitOptions struct {
	// Timeout for the operation
	Timeout time.Duration
	// Author name
	AuthorName string
	// Author email address
	AuthorEmail string
	// Amend last commit?
	Amend bool
}

// Commit commits the staged files with the given message, returning the hash of
// commit
func (r Repository) Commit(msg string, opt *CommitOptions) (Hash, error) {
	if opt == nil {
		opt = &CommitOptions{}
	}

	args := []string{"commit"}
	if opt.Amend {
		args = append(args, "--amend")
	} else {
		args = append(args, "-m", msg)
	}

	var env []string
	if opt.AuthorName != "" || opt.AuthorEmail != "" {
		env = []string{
			fmt.Sprintf("GIT_AUTHOR_NAME=%v", opt.AuthorName),
			fmt.Sprintf("GIT_AUTHOR_EMAIL=%v", opt.AuthorEmail),
			fmt.Sprintf("GIT_COMMITTER_NAME=%v", opt.AuthorName),
			fmt.Sprintf("GIT_COMMITTER_EMAIL=%v", opt.AuthorEmail),
		}
	}
	if _, err := r.run(env, opt.Timeout, "commit", "-m", msg); err != nil {
		return Hash{}, err
	}
	out, err := r.run(nil, 0, "rev-parse", "HEAD")
	if err != nil {
		return Hash{}, err
	}
	return ParseHash(out)
}

// Optional settings for Repository.Checkout
type CheckoutOptions struct {
	// Timeout for the operation
	Timeout time.Duration
}

// Checkout performs a checkout of a reference.
func (r Repository) Checkout(ref string, opt *CheckoutOptions) error {
	if opt == nil {
		opt = &CheckoutOptions{}
	}
	if _, err := r.run(nil, opt.Timeout, "checkout", ref); err != nil {
		return err
	}
	return nil
}

// Optional settings for Repository.Log
type LogOptions struct {
	// The git reference to the oldest commit in the range to query.
	From string
	// The git reference to the newest commit in the range to query.
	To string
	// Timeout for the operation
	Timeout time.Duration
}

const logPrettyFormatArg = "--pretty=format:ǁ%Hǀ%cIǀ%an <%ae>ǀ%sǀ%b"

// Log returns the list of commits between two references (inclusive).
// The first returned commit is the most recent.
func (r Repository) Log(opt *LogOptions) ([]CommitInfo, error) {
	if opt == nil {
		opt = &LogOptions{}
	}
	args := []string{"log"}
	rng := "HEAD"
	if opt.To != "" {
		rng = opt.To
	}
	if opt.From != "" {
		rng = opt.From + "^.." + rng
	}
	args = append(args, rng, logPrettyFormatArg)
	out, err := r.run(nil, opt.Timeout, args...)
	if err != nil {
		return nil, err
	}
	return parseLog(out)
}

// Optional settings for Repository.LogBetween
type LogBetweenOptions struct {
	// Timeout for the operation
	Timeout time.Duration
}

// LogBetween returns the list of commits between two timestamps
// The first returned commit is the most recent.
func (r Repository) LogBetween(since, until time.Time, opt *LogBetweenOptions) ([]CommitInfo, error) {
	if opt == nil {
		opt = &LogBetweenOptions{}
	}
	args := []string{"log",
		"--since", since.Format(time.RFC3339),
		"--until", until.Format(time.RFC3339),
		logPrettyFormatArg,
	}
	out, err := r.run(nil, opt.Timeout, args...)
	if err != nil {
		return nil, err
	}
	return parseLog(out)
}

// FileStats describes the changes to a given file in a commit
type FileStats struct {
	Insertions int
	Deletions  int
}

// CommitStats is a map of file to FileStats
type CommitStats map[string]FileStats

// Optional settings for Repository.Stats
type StatsOptions struct {
	// Timeout for the operation
	Timeout time.Duration
}

// StatsOptions returns the statistics for a given change
func (r Repository) Stats(commit CommitInfo, opt *StatsOptions) (CommitStats, error) {
	if opt == nil {
		opt = &StatsOptions{}
	}

	hash := commit.Hash.String()
	args := []string{"diff", "--numstat", hash, hash + "^"}
	out, err := r.run(nil, opt.Timeout, args...)
	if err != nil {
		return nil, err
	}
	stats := CommitStats{}
	for _, line := range strings.Split(out, "\n") {
		if out == "" {
			continue
		}
		parts := strings.Split(line, "\t")
		if len(parts) != 3 {
			return nil, fmt.Errorf("failed to parse stat line: '%v'", line)
		}
		insertions, deletions := 0, 0
		if parts[0] != "-" {
			insertions, err = strconv.Atoi(parts[0])
			if err != nil {
				return nil, fmt.Errorf("failed to stat insertions '%v': %w", parts[0], err)
			}
		}
		if parts[1] != "-" {
			deletions, err = strconv.Atoi(parts[1])
			if err != nil {
				return nil, fmt.Errorf("failed to stat deletions '%v': %w", parts[1], err)
			}
		}
		file := parts[2]
		stats[file] = FileStats{Insertions: insertions, Deletions: deletions}
	}
	return stats, nil
}

// CommitInfo describes a single git commit
type CommitInfo struct {
	Hash        Hash
	Date        time.Time
	Author      string
	Subject     string
	Description string
}

// Optional settings for Repository.ConfigOptions
type ConfigOptions struct {
	// Timeout for the operation
	Timeout time.Duration
}

// Config returns the git configuration values for the repo
func (r Repository) Config(opt *ConfigOptions) (map[string]string, error) {
	if opt == nil {
		opt = &ConfigOptions{}
	}
	text, err := r.run(nil, opt.Timeout, "config", "-l")
	if err != nil {
		return nil, err
	}
	lines := strings.Split(text, "\n")
	out := make(map[string]string, len(lines))
	for _, line := range lines {
		idx := strings.Index(line, "=")
		if idx > 0 {
			key, value := line[:idx], line[idx+1:]
			out[key] = value
		}
	}
	return out, nil
}

func (r Repository) run(env []string, timeout time.Duration, args ...string) (string, error) {
	return r.Git.run(r.Path, env, timeout, args...)
}

func (g Git) run(dir string, env []string, timeout time.Duration, args ...string) (string, error) {
	if timeout == 0 {
		timeout = DefaultTimeout
	}
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()
	cmd := exec.CommandContext(ctx, g.exe, args...)
	cmd.Dir = dir
	if env != nil {
		// Godocs for exec.Cmd.Env:
		// "If Env contains duplicate environment keys, only the last value in
		// the slice for each duplicate key is used.
		cmd.Env = append(os.Environ(), env...)
	}
	if g.LogAllActions {
		fmt.Printf("%v> %v %v\n", dir, g.exe, strings.Join(args, " "))
	}
	out, err := cmd.CombinedOutput()
	if g.LogAllActions {
		fmt.Println(string(out))
	}
	if err != nil {
		msg := fmt.Sprintf("%v> %v %v failed:", dir, g.exe, strings.Join(args, " "))
		if err := ctx.Err(); err != nil {
			msg += "\n" + err.Error()
		}
		return string(out), fmt.Errorf("%s\n  %w\n%v", msg, err, string(out))
	}
	return strings.TrimSpace(string(out)), nil
}

func parseLog(str string) ([]CommitInfo, error) {
	msgs := strings.Split(str, "ǁ")
	cls := make([]CommitInfo, 0, len(msgs))
	for _, s := range msgs {
		if parts := strings.Split(s, "ǀ"); len(parts) == 5 {
			hash, err := ParseHash(parts[0])
			if err != nil {
				return nil, err
			}
			date, err := time.Parse(time.RFC3339, parts[1])
			if err != nil {
				return nil, err
			}
			cl := CommitInfo{
				Hash:        hash,
				Date:        date,
				Author:      strings.TrimSpace(parts[2]),
				Subject:     strings.TrimSpace(parts[3]),
				Description: strings.TrimSpace(parts[4]),
			}

			cls = append(cls, cl)
		}
	}
	return cls, nil
}
