// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package gitrepo provides operations on git repos.
package gitrepo

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"strings"
	"time"

	"github.com/go-git/go-billy/v5/memfs"
	"github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/plumbing"
	"github.com/go-git/go-git/v5/plumbing/object"
	"github.com/go-git/go-git/v5/storage/memory"
	"golang.org/x/tools/txtar"
	"golang.org/x/vulndb/internal/derrors"
	"golang.org/x/vulndb/internal/observe"
	"golang.org/x/vulndb/internal/worker/log"
)

// Clone returns a bare repo by cloning the repo at repoURL.
func Clone(ctx context.Context, repoURL string) (repo *git.Repository, err error) {
	defer derrors.Wrap(&err, "gitrepo.Clone(%q)", repoURL)
	ctx, span := observe.Start(ctx, "gitrepo.Clone")
	defer span.End()

	return CloneAt(ctx, repoURL, plumbing.HEAD)
}

// CloneAt returns a bare repo by cloning the repo at repoURL at the given ref.
func CloneAt(ctx context.Context, repoURL string, ref plumbing.ReferenceName) (repo *git.Repository, err error) {
	log.Infof(ctx, "Cloning repo %q at %s", repoURL, ref)
	return git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
		URL:           repoURL,
		ReferenceName: ref,
		SingleBranch:  true,
		Depth:         1,
		Tags:          git.NoTags,
	})
}

// PlainClone returns a (non-bare) repo with its history by cloning the repo at repoURL.
func PlainClone(ctx context.Context, dir, repoURL string) (repo *git.Repository, err error) {
	defer derrors.Wrap(&err, "gitrepo.PlainClone(%q)", repoURL)
	ctx, span := observe.Start(ctx, "gitrepo.PlainClone")
	defer span.End()

	log.Infof(ctx, "Plain cloning repo %q at HEAD", repoURL)
	return git.PlainCloneContext(ctx, dir, false, &git.CloneOptions{
		URL:           repoURL,
		ReferenceName: plumbing.HEAD,
		SingleBranch:  true, // allow branches other than master
		Depth:         0,    // pull in history
		Tags:          git.NoTags,
	})
}

// PlainCloneWith returns a (non-bare) repo with its history by cloning the repo with the given options opt.
func PlainCloneWith(ctx context.Context, dir string, opts *git.CloneOptions) (repo *git.Repository, err error) {
	defer derrors.Wrap(&err, "gitrepo.PlainCloneWith(%q)", opts.URL)
	ctx, span := observe.Start(ctx, "gitrepo.PlainCloneWith")
	defer span.End()

	log.Infof(ctx, "Plain cloning repo %q at HEAD with options", opts.URL)
	return git.PlainCloneContext(ctx, dir, false, opts)
}

// Open returns a repo by opening the repo at the local path dirpath.
func Open(ctx context.Context, dirpath string) (repo *git.Repository, err error) {
	defer derrors.Wrap(&err, "gitrepo.Open(%q)", dirpath)
	ctx, span := observe.Start(ctx, "gitrepo.Open")
	defer span.End()

	log.Infof(ctx, "Opening repo at %q", dirpath)
	repo, err = git.PlainOpen(dirpath)
	if err != nil {
		return nil, err
	}
	return repo, nil
}

// CloneOrOpen clones repoPath if it is an HTTP(S) URL, or opens it from the
// local disk otherwise.
func CloneOrOpen(ctx context.Context, repoPath string) (*git.Repository, error) {
	if strings.HasPrefix(repoPath, "http://") || strings.HasPrefix(repoPath, "https://") {
		return Clone(ctx, repoPath)
	}
	return Open(ctx, repoPath)
}

// Root returns the root tree of the repo at HEAD.
func Root(repo *git.Repository) (root *object.Tree, err error) {
	head, err := HeadCommit(repo)
	if err != nil {
		return nil, err
	}
	return RootAt(repo, head)
}

// RootAt returns the root tree of the repo at the given commit.
func RootAt(repo *git.Repository, commit *object.Commit) (root *object.Tree, err error) {
	return repo.TreeObject(commit.TreeHash)
}

// TxtarRepoAndHead reads a txtar repo into a single-commit repository,
// and returns the repo and its head commit.
// Intended for testing.
func TxtarRepoAndHead(file string) (*git.Repository, *object.Commit, error) {
	repo, err := ReadTxtarRepo(file, time.Now())
	if err != nil {
		return nil, nil, err
	}
	commit, err := HeadCommit(repo)
	if err != nil {
		return nil, nil, err
	}
	return repo, commit, nil
}

// HeadCommit returns the commit at the repo HEAD.
func HeadCommit(repo *git.Repository) (*object.Commit, error) {
	h, err := HeadHash(repo)
	if err != nil {
		return nil, err
	}
	commit, err := repo.CommitObject(h)
	if err != nil {
		return nil, err
	}
	return commit, nil
}

// ReadTxtarRepo converts a txtar file to a single-commit
// repo. It is intended for testing.
func ReadTxtarRepo(filename string, now time.Time) (_ *git.Repository, err error) {
	defer derrors.Wrap(&err, "ReadTxtarRepo(%q)", filename)

	ar, err := txtar.ParseFile(filename)
	if err != nil {
		return nil, err
	}

	return FromTxtarArchive(ar, now)
}

func FromTxtarArchive(ar *txtar.Archive, now time.Time) (_ *git.Repository, err error) {
	mfs := memfs.New()
	for _, f := range ar.Files {
		file, err := mfs.Create(f.Name)
		if err != nil {
			return nil, err
		}
		if _, err := file.Write(f.Data); err != nil {
			return nil, err
		}
		if err := file.Close(); err != nil {
			return nil, err
		}
	}

	repo, err := git.Init(memory.NewStorage(), mfs)
	if err != nil {
		return nil, err
	}
	wt, err := repo.Worktree()
	if err != nil {
		return nil, err
	}
	for _, f := range ar.Files {
		if _, err := wt.Add(f.Name); err != nil {
			return nil, err
		}
	}
	_, err = wt.Commit("", &git.CommitOptions{All: true, Author: &object.Signature{
		Name:  "Joe Random",
		Email: "joe@example.com",
		When:  now,
	}})
	if err != nil {
		return nil, err
	}
	return repo, nil
}

// HeadHash returns the hash of the repo's HEAD.
func HeadHash(repo *git.Repository) (plumbing.Hash, error) {
	ref, err := repo.Reference(plumbing.HEAD, true)
	if err != nil {
		return plumbing.ZeroHash, err
	}
	return ref.Hash(), nil
}

// ParseGitHubRepo parses a string of the form owner/repo or
// github.com/owner/repo.
func ParseGitHubRepo(s string) (owner, repoName string, err error) {
	parts := strings.Split(s, "/")
	switch len(parts) {
	case 2:
		return parts[0], parts[1], nil
	case 3:
		if parts[0] != "github.com" {
			return "", "", fmt.Errorf("%q is not in the form {github.com/}owner/repo", s)
		}
		return parts[1], parts[2], nil
	default:
		return "", "", fmt.Errorf("%q is not in the form {github.com/}owner/repo", s)
	}
}

// ReferenceName is a git reference.
type ReferenceName struct{ plumbing.ReferenceName }

var (
	HeadReference = ReferenceName{plumbing.HEAD}                                       // HEAD
	MainReference = ReferenceName{plumbing.NewRemoteReferenceName("origin", "master")} // origin/master
)

// Dates is the oldest and newest commit timestamps for a file.
type Dates struct {
	Oldest, Newest time.Time
}

// AllCommitDates returns the oldest and newest commit timestamps for every
// file in the repo at the given reference, where the filename begins with
// prefix. The supplied prefix should include the trailing /.
func AllCommitDates(repo *git.Repository, refName ReferenceName, prefix string) (dates map[string]Dates, err error) {
	defer derrors.Wrap(&err, "AllCommitDates(%q)", prefix)

	ref, err := repo.Reference(refName.ReferenceName, true)
	if err != nil {
		return nil, err
	}
	commit, err := repo.CommitObject(ref.Hash())
	if err != nil {
		return nil, err
	}
	dates = make(map[string]Dates)
	iter := object.NewCommitPreorderIter(commit, nil, nil)
	commit, err = iter.Next()
	if err != nil {
		return nil, err
	}
	for commit != nil {
		parentCommit, err := iter.Next()
		if err != nil {
			if err != io.EOF {
				return nil, err
			}
			parentCommit = nil
		}

		currentTree, err := commit.Tree()
		if err != nil {
			return nil, err
		}

		var parentTree *object.Tree
		if parentCommit != nil {
			parentTree, err = parentCommit.Tree()
			if err != nil {
				return nil, err
			}
		}

		changes, err := object.DiffTree(currentTree, parentTree)
		if err != nil {
			return nil, err
		}

		for _, change := range changes {
			name := change.To.Name
			if change.From.Name != "" {
				name = change.From.Name
			}
			when := commit.Committer.When.UTC()
			if !strings.HasPrefix(name, prefix) {
				continue
			}
			d := dates[name]
			if d.Oldest.IsZero() || when.Before(d.Oldest) {
				if d.Oldest.After(d.Newest) {
					d.Newest = d.Oldest
				}
				d.Oldest = when
			}
			if when.After(d.Newest) {
				d.Newest = when
			}
			dates[name] = d
		}

		commit = parentCommit
	}
	return dates, nil
}

func ReadAll(repo *git.Repository, hash plumbing.Hash) ([]byte, error) {
	blob, err := repo.BlobObject(hash)
	if err != nil {
		return nil, err
	}
	r, err := blob.Reader()
	if err != nil {
		return nil, err
	}
	return io.ReadAll(r)
}

type File interface {
	Name() string
	ReadAll(*git.Repository) ([]byte, error)
}

// Parse unmarshals the contents of f.
func Parse[T any](repo *git.Repository, f File) (_ T, raw []byte, _ error) {
	var zero T
	b, err := f.ReadAll(repo)
	if err != nil {
		return zero, nil, err
	}
	if len(b) == 0 {
		return zero, nil, fmt.Errorf("%s is empty", f.Name())
	}
	v := new(T)
	if err := json.Unmarshal(b, v); err != nil {
		return zero, nil, err
	}
	return *v, b, nil
}
