// Copyright 2024 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 report

import (
	"context"
	"os"
	"strings"

	"github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/plumbing"
	"golang.org/x/vulndb/cmd/vulnreport/log"
	"golang.org/x/vulndb/internal/derrors"
	"golang.org/x/vulndb/internal/gitrepo"
)

// expandGitCommits expands git repositories and names to commits.
// Expands versions in r of the form <url>@<name> where url starts with
// one of {'git://', 'https://', 'http://', 'ssh://', 'git+ssh://'}
// and name is the name of a git branch or git tag to a git commit
// hash. Any version that is successfully expanded is replaced.
func expandGitCommits(r *Report) {
	// Find repos in versions to expand
	repos := make(map[string][]string) // url -> names
	perVersion := func(v *Version) {
		if v == nil {
			return
		}
		if b, a, f := cutRepoUrl(v.Version); f {
			repos[b] = append(repos[b], a)
		}
	}
	for _, m := range r.Modules {
		for _, v := range m.Versions {
			perVersion(v)
		}
		perVersion((*Version)(m.VulnerableAt))
	}

	if len(repos) == 0 { // no repos to expand
		return
	}

	log.Infof("Expanding git urls for %d repos", len(repos))

	// Create scratch directory.
	scratch, err := os.MkdirTemp("", "expand-git-references")
	if err != nil {
		log.Err("failed to create scratch directory for ExpandGitReferences")
		return
	}
	defer func() {
		_ = os.RemoveAll(scratch)
	}()

	// expand references and compute replacements
	replacements := make(map[string]string)
	for repo, names := range repos {
		commits, err := gitNameToCommits(scratch, repo, names)
		if err != nil {
			log.Infof("expandGitCommits(%v, %v) failed with: %v", repo, names, err)
			continue
		}
		for name, c := range commits {
			replacements[repo+"@"+name] = c
		}
	}

	if len(replacements) == 0 { // no replacements created
		return
	}

	// Replace all.
	replaceVersion := func(v *Version) {
		if r, ok := replacements[v.Version]; ok {
			v.Version = r
		}
	}
	for _, m := range r.Modules {
		for _, v := range m.Versions {
			replaceVersion(v)
		}
		replaceVersion(m.VulnerableAt)
	}
}

func cutRepoUrl(v string) (string, string, bool) {
	prefixes := map[string]bool{
		"https://":   true,
		"http://":    true,
		"git://":     true,
		"git+ssh://": true,
		"ssh://":     true,
	}
	for p := range prefixes {
		if strings.HasPrefix(v, p) {
			return strings.Cut(v, "@")
		}
	}
	return v, "", false
}

// gitNameToCommits returns a mapping from the git repo at repoURL
// and returns a mapping for the branches and tags in names to
// a commit hash.
func gitNameToCommits(dir string, repoURL string, names []string) (_ map[string]string, err error) {
	defer derrors.Wrap(&err, "gitNameToCommits(%q, %q, %v)", dir, repoURL, names)

	repoRoot, err := os.MkdirTemp(dir, "git*")
	if err != nil {
		return nil, err
	}

	ctx := context.Background()
	repo, err := gitrepo.PlainCloneWith(ctx, repoRoot, &git.CloneOptions{
		URL:           repoURL,
		ReferenceName: plumbing.HEAD,
		SingleBranch:  true, // allow branches other than master
		Depth:         0,    // pull in history
		// Leaves Tags the default value.
	})
	if err != nil {
		return nil, err
	}

	resolveName := func(name string) (string, bool) {
		// commit hash?
		if c, err := repo.CommitObject(plumbing.NewHash(name)); err == nil {
			return c.Hash.String(), true
		}

		// branch name?
		if b, err := repo.Branch(name); err == nil {
			if ref, err := repo.Reference(b.Merge, true); err == nil {
				if h := ref.Hash(); !h.IsZero() {
					return h.String(), true
				}
			}
		}

		// tag name?
		if ref, err := repo.Tag(name); err == nil {
			if h := ref.Hash(); !h.IsZero() {
				return h.String(), true
			}
		}

		return "", false
	}

	results := make(map[string]string)
	for _, name := range names {
		if r, ok := resolveName(name); ok {
			results[name] = r
		}
	}
	return results, nil
}
