// 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 main

import (
	"context"
	"fmt"
	"strconv"
	"strings"
	"sync"

	"golang.org/x/vulndb/cmd/vulnreport/log"
	"golang.org/x/vulndb/internal/ghsa"
	"golang.org/x/vulndb/internal/gitrepo"
	"golang.org/x/vulndb/internal/issues"
	"golang.org/x/vulndb/internal/proxy"
	"golang.org/x/vulndb/internal/report"
)

type duplicates struct {
	gc         *ghsa.Client
	ic         *issues.Client
	pc         *proxy.Client
	rc         *report.Client
	trackerURL string

	isses map[string]*issues.Issue

	// protects aliasesToIssues
	mu              sync.Mutex
	aliasesToIssues map[string][]int
}

func (*duplicates) name() string { return "duplicates" }

func (*duplicates) usage() (string, string) {
	const desc = "finds likely duplicates of the given Github issue (with no args, looks at all open issues)"
	return "<no args> | " + ghIssueArgs, desc
}

func (*duplicates) close() error {
	return nil
}

func (c *duplicates) setup(ctx context.Context) error {
	if *githubToken == "" {
		return fmt.Errorf("githubToken must be provided")
	}
	owner, repoName, err := gitrepo.ParseGitHubRepo(*issueRepo)
	if err != nil {
		return err
	}

	c.trackerURL = fmt.Sprintf("https://github.com/%s/%s/issues", owner, repoName)
	c.ic = issues.NewClient(ctx, &issues.Config{Owner: owner, Repo: repoName, Token: *githubToken})
	c.gc = ghsa.NewClient(ctx, *githubToken)
	c.pc = proxy.NewDefaultClient()
	c.isses = make(map[string]*issues.Issue)

	localRepo, err := gitrepo.Open(ctx, ".")
	if err != nil {
		return err
	}
	rc, err := report.NewClient(localRepo)
	if err != nil {
		return err
	}
	c.rc = rc

	c.aliasesToIssues = make(map[string][]int)

	return nil
}

func (d *duplicates) parseArgs(ctx context.Context, args []string) (issNums []string, err error) {
	if len(args) > 0 {
		return argsToIDs(args)
	}

	// If no arguments are provided, operate on all open issues.
	is, err := d.ic.Issues(ctx, issues.IssuesOptions{State: "open"})
	if err != nil {
		return nil, err
	}
	log.Infof("found %d open issues", len(is))

	for _, iss := range is {
		n := strconv.Itoa(iss.Number)
		d.isses[n] = iss
		issNums = append(issNums, n)
	}

	return issNums, nil
}

func (d *duplicates) run(ctx context.Context, issNum string) (err error) {
	iss, ok := d.isses[issNum]
	if !ok {
		n, err := strconv.Atoi(issNum)
		if err != nil {
			return err
		}
		iss, err = d.ic.Issue(ctx, n)
		if err != nil {
			return err
		}
	}

	parsed, err := parseGithubIssue(iss, d.pc, false)
	if err != nil {
		return err
	}

	if len(parsed.aliases) == 0 {
		log.Infof("no aliases found for issue #%d (%q), skipping", iss.Number, iss.Title)
		return
	}

	aliases := allAliases(ctx, parsed.aliases, d.gc)
	var allXrefs []string
	for _, a := range aliases {
		var xrefs []string

		// Find existing reports with this alias.
		if reports := d.rc.ReportsByAlias(a); len(reports) != 0 {
			for _, r := range reports {
				fname, err := r.YAMLFilename()
				if err != nil {
					fname = r.ID
				}
				xrefs = append(xrefs, fname)
			}
		}

		// Find other open issues with this alias.
		if issNums, ok := d.aliasesToIssues[a]; ok {
			for _, in := range issNums {
				xrefs = append(xrefs, d.githubURL(in))
			}
		}

		d.addAlias(a, iss.Number)

		if len(xrefs) != 0 {
			allXrefs = append(allXrefs, fmt.Sprintf("#%d shares alias %s with %s", iss.Number, a, strings.Join(xrefs, ", ")))
		}
	}

	if len(allXrefs) != 0 {
		log.Outf("%s is a likely duplicate:\n - %s", d.githubURL(iss.Number), strings.Join(allXrefs, "\n - "))
	} else {
		log.Infof("found no existing reports or open issues with aliases in issue #%d", iss.Number)
	}
	return nil
}

func (d *duplicates) githubURL(n int) string {
	return fmt.Sprintf("%s/%d", d.trackerURL, n)
}

func (d *duplicates) addAlias(a string, n int) {
	d.mu.Lock()
	defer d.mu.Unlock()

	d.aliasesToIssues[a] = append(d.aliasesToIssues[a], n)
}
