package git

import (
	"context"
	"fmt"
	"io/fs"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"time"

	"go.skia.org/infra/go/exec"
	"go.skia.org/infra/go/git/git_common"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/vfs"
)

const (
	// MasterBranch is the name of the default branch for most repositories.
	MasterBranch = git_common.MasterBranch
	// MainBranch is the name of the default branch for some
	// repositories which don't use MasterBranch.
	// TODO(rmistry): Delete this after http://skbug.com/11842 is resolved.
	MainBranch = git_common.MainBranch
	// DefaultRef is the fully-qualified ref name of the default branch for most
	// repositories.
	DefaultRef = git_common.DefaultRef
	// DefaultRemote is the name of the default remote repository.
	DefaultRemote = git_common.DefaultRemote
	// DefaultRemoteBranch is the name of the default branch in the default
	// remote repository, for most repos.
	DefaultRemoteBranch = git_common.DefaultRemoteBranch
)

var (
	commitHashRegex = regexp.MustCompile(`^[a-f0-9]+$`)

	// This regex is taken from:
	// https://source.chromium.org/chromium/infra/infra/+/master:go/src/go.chromium.org/luci/common/git/footer/footer.go?q=%22%5E%5Cs*(%5B%5Cw-%5D%2B):%20*(.*)$%22&ss=chromium
	trailerRegex = regexp.MustCompile(`^\s*([\w-]+): *(.*)$`)
)

// Types of git objects.
const (
	ObjectTypeBlob   ObjectType = "blob"
	ObjectTypeCommit ObjectType = "commit"
	ObjectTypeTree   ObjectType = "tree"
)

// ObjectType represents a Git object type.
type ObjectType string

// Clone runs "git clone" into the given destination directory. Most callers
// should use NewRepo or NewCheckout instead.
func Clone(ctx context.Context, repoUrl, dest string, mirror bool) error {
	git, err := Executable(ctx)
	if err != nil {
		return skerr.Wrap(err)
	}
	if mirror {
		// We don't use a "real" mirror, since that syncs ALL refs,
		// including every patchset of every CL that gets uploaded. Instead,
		// we use a bare clone and then add the "mirror" config after
		// cloning. It would be equivalent to use --mirror and then update
		// the refspec to only sync the branches, but that would force the
		// initial clone step to sync every ref.
		if _, err := exec.RunCwd(ctx, ".", git, "clone", "--bare", repoUrl, dest); err != nil {
			return fmt.Errorf("Failed to clone repo: %s", err)
		}
		if _, err := exec.RunCwd(ctx, dest, git, "config", "remote.origin.mirror", "true"); err != nil {
			return fmt.Errorf("Failed to set git mirror config: %s", err)
		}
		if _, err := exec.RunCwd(ctx, dest, git, "config", "remote.origin.fetch", "refs/heads/*:refs/heads/*"); err != nil {
			return fmt.Errorf("Failed to set git mirror config: %s", err)
		}
		if _, err := exec.RunCwd(ctx, dest, git, "fetch", "--force", "--all"); err != nil {
			return fmt.Errorf("Failed to set git mirror config: %s", err)
		}
	} else {
		if _, err := exec.RunCwd(ctx, ".", git, "clone", repoUrl, dest); err != nil {
			return fmt.Errorf("Failed to clone repo: %s", err)
		}
	}
	return nil
}

// LogFromTo returns a string which is used to log from one commit to another.
// It is important to note that:
//   - The results may include the second commit but will not include the first.
//   - The results include all commits reachable from the first commit which are
//     not reachable from the second, ie. if there is a merge in the given
//     range, the results will include that line of history and not just the
//     commits which are descendants of the first commit. If you want only commits
//     which are ancestors of the second commit AND descendants of the first, you
//     should use LogLinear, but note that the results will be empty if the first
//     commit is not an ancestor of the second, ie. they're on different branches.
func LogFromTo(from, to string) string {
	return fmt.Sprintf("%s..%s", from, to)
}

// NormalizeURL strips everything from the URL except for the host and the path.
// A trailing ".git" is also stripped. The purpose is to allow for small
// variations in repo URL to be recognized as the same repo. The URL needs to
// contain a valid transport protocol, e.g. https, ssh.
// These URLs will all return 'github.com/skia-dev/textfiles':
//
//	"https://github.com/skia-dev/textfiles.git"
//	"ssh://git@github.com/skia-dev/textfiles"
//	"ssh://git@github.com:skia-dev/textfiles.git"
func NormalizeURL(inputURL string) (string, error) {
	// If the scheme is ssh we have to account for the scp-like syntax with a ':'
	const ssh = "ssh://"
	if strings.HasPrefix(inputURL, ssh) {
		inputURL = ssh + strings.Replace(inputURL[len(ssh):], ":", "/", 1)
	}

	parsedURL, err := url.Parse(inputURL)
	if err != nil {
		return "", skerr.Wrapf(err, "parsing inputURL")
	}

	host := parsedURL.Host
	// Trim trailing slashes and the ".git" extension.
	path := strings.TrimRight(strings.TrimSuffix(parsedURL.Path, ".git"), "/")
	path = "/" + strings.TrimLeft(path, "/:")
	return host + path, nil
}

// DeleteLockFiles finds and deletes Git lock files within the given workdir.
func DeleteLockFiles(ctx context.Context, workdir string) error {
	sklog.Infof("Looking for git lockfiles in %s", workdir)
	knownLockFiles := []string{"index.lock", "HEAD.lock", "commit-graph.lock"}
	foundLockFiles := []string{}
	for _, lockFile := range knownLockFiles {
		output, err := exec.RunCwd(ctx, workdir, "find", ".", "-name", lockFile)
		if err != nil {
			return err
		}
		output = strings.TrimSpace(output)
		if output != "" {
			foundLockFiles = append(foundLockFiles, strings.Split(output, "\n")...)
		}
	}
	if len(foundLockFiles) > 0 {
		for _, f := range foundLockFiles {
			fp := filepath.Join(workdir, f)
			sklog.Warningf("Removing git lockfile: %s", fp)
			if err := os.Remove(fp); err != nil {
				return err
			}
		}
	} else {
		sklog.Info("No lockfiles found.")
	}
	return nil
}

// ParseDir parses the contents of a directory. Expects the contents to be in
// the format used by git, ie. lines taking the form:
//
// mode tree|blob hash name
func ParseDir(contents []byte) ([]fs.FileInfo, error) {
	rv := []fs.FileInfo{}
	for _, line := range strings.Split(strings.TrimSpace(string(contents)), "\n") {
		if line == "" {
			continue
		}
		// Lines are formatted as follows:
		// mode tree|blob hash name
		fields := strings.Fields(line)
		if len(fields) != 4 {
			return nil, skerr.Fmt("Expected format \"mode tree|blob hash name\" but got:\n %s", contents)
		}
		// We can't know the size of the directory contents with the information
		// we're given.
		size := 0
		fi, err := MakeFileInfo(fields[3], fields[0], ObjectType(fields[1]), size)
		if err != nil {
			return nil, skerr.Wrap(err)
		}
		rv = append(rv, fi)
	}
	return rv, nil
}

// MakeFileInfo returns an fs.FileInfo with the given information.
func MakeFileInfo(name, mode string, typ ObjectType, size int) (fs.FileInfo, error) {
	modeInt, err := strconv.ParseUint(mode, 8, 32)
	if err != nil {
		return nil, skerr.Wrapf(err, "invalid file mode %q", mode)
	}
	fileMode := os.FileMode(modeInt)
	isDir := false
	if typ == ObjectTypeTree {
		isDir = true
		fileMode = fileMode | os.ModeDir
	}
	if typ != ObjectTypeTree && typ != ObjectTypeBlob && typ != ObjectTypeCommit {
		return nil, skerr.Fmt("Invalid file type %q", typ)
	}
	return vfs.FileInfo{
		Name: path.Base(name),
		Size: int64(size),
		Mode: fileMode,
		// Gitiles doesn't give us the modification timestamp. We could make
		// one up using the timestamp of the commit which last touched the
		// file, but that would require an extra request.
		ModTime: time.Time{},
		IsDir:   isDir,
		Sys:     nil,
	}.Get(), nil
}

// SplitTrailers splits a commit message into a main commit message body and
// trailers footer.  Assumes that the commit message is already well-formed with
// respect to trailers, ie. there is an empty line between the last body
// paragraph and the single trailers paragraph, which contains only lines in
// "key: value" format.
func SplitTrailers(commitMsg string) ([]string, []string) {
	// Split the commit message into paragraphs.
	if commitMsg == "" {
		return []string{}, []string{}
	}
	lines := strings.Split(strings.TrimSpace(commitMsg), "\n")
	paragraphs := [][]string{}
	var paragraph []string
	for _, line := range lines {
		paragraph = append(paragraph, line)
		if line == "" {
			if len(paragraph) > 0 {
				paragraphs = append(paragraphs, paragraph)
			}
			paragraph = []string{}
		}
	}
	if len(paragraph) > 0 {
		paragraphs = append(paragraphs, paragraph)
	}

	// If the last paragraph consists of valid trailers, split off those lines,
	// otherwise include them as part of the main commit message body.
	if len(paragraphs) < 1 {
		return lines, []string{}
	}
	trailerLines := paragraphs[len(paragraphs)-1]
	for _, line := range trailerLines {
		if !trailerRegex.MatchString(line) {
			// At least one line in the last paragraph does not fit the trailer
			// format; assume there are no trailers.
			return lines, []string{}
		}
	}
	bodyLines := make([]string, 0, len(paragraphs[0]))
	for _, paragraph := range paragraphs[:len(paragraphs)-1] {
		bodyLines = append(bodyLines, paragraph...)
	}
	return bodyLines, trailerLines
}

// JoinTrailers joins a main commit message body with a trailers footer.
func JoinTrailers(bodyLines, trailers []string) string {
	commitMsg := make([]string, 0, len(bodyLines)+len(trailers)+1)
	commitMsg = append(commitMsg, bodyLines...)
	if len(commitMsg) > 0 && commitMsg[len(commitMsg)-1] != "" {
		commitMsg = append(commitMsg, "")
	}
	commitMsg = append(commitMsg, trailers...)
	return strings.Join(commitMsg, "\n")
}

// AddTrailer adds a trailer to the given commit message.
func AddTrailer(commitMsg, trailer string) (string, error) {
	if !trailerRegex.MatchString(trailer) {
		return "", skerr.Fmt("%q is not a valid git trailer", trailer)
	}
	body, trailers := SplitTrailers(commitMsg)
	trailers = append(trailers, trailer)
	return JoinTrailers(body, trailers), nil
}

// FullyQualifiedBranchName ensures that the branch has the refs/heads/ prefix.
func FullyQualifiedBranchName(branch string) string {
	if strings.HasPrefix(branch, git_common.RefsHeadsPrefix) {
		return branch
	}
	return git_common.RefsHeadsPrefix + branch
}

// BranchBaseName ensures that the branch does not have the refs/heads/ prefix.
func BranchBaseName(branch string) string {
	return strings.TrimPrefix(branch, git_common.RefsHeadsPrefix)
}

// GetFootersMap parses the specified commit msg and returns it's footers.
// Invalid footer formats are logged.
// Eg: commit msg: "test test\n\nBug: skia:123\nTested: true" will return
// {"skia": "123", "Tested": "true"}.
func GetFootersMap(commitMsg string) map[string]string {
	footersMap := map[string]string{}
	_, footers := SplitTrailers(commitMsg)
	for _, f := range footers {
		rs := trailerRegex.FindStringSubmatch(f)
		if len(rs) != 3 {
			sklog.Errorf("Could not parse footer %s from the commitMsg %s", f, commitMsg)
			continue
		}
		footersMap[rs[1]] = rs[2]
	}

	return footersMap
}

// GetBoolFooterVal looks for the specified footer in the footersMap and returns
// it's boolean value. If the footer is not found then false is returned.
// If the value is not boolean then false is returned and an error is logged.
func GetBoolFooterVal(footersMap map[string]string, footer string, issue int64) bool {
	if val, ok := footersMap[string(footer)]; ok {
		b, err := strconv.ParseBool(val)
		if err != nil {
			sklog.Errorf("Could not parse bool value out of \"%s: %s\" in %d", footer, val, issue)
			return false
		} else {
			if b {
				return b
			}
		}
	}
	return false
}

// GetStringFooterVal looks for the specified footer in the footersMap and returns
// it's strings value. If the footer is not found then an empty string is
// returned.
func GetStringFooterVal(footersMap map[string]string, footer string) string {
	if val, ok := footersMap[string(footer)]; ok {
		return val
	}
	return ""
}

// IsFullCommitHash returns true if the given string looks like a full 40-
// character Git commit hash.
func IsFullCommitHash(s string) bool {
	return IsCommitHash(s) && len(s) == 40
}

// IsCommitHash returns true if the given string looks like a valid (possibly
// shortened) Git commit hash.
func IsCommitHash(s string) bool {
	return commitHashRegex.MatchString(s) && len(s) >= 4 && len(s) <= 40
}
