// 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"
	"flag"
	"fmt"
	"os"
	"strconv"
	"strings"

	"golang.org/x/vulndb/cmd/vulnreport/log"
	"golang.org/x/vulndb/internal/genai"
	"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"
)

var (
	dry  = flag.Bool("dry", false, "for create-excluded, do not commit files")
	user = flag.String("user", "", "for create-excluded, only consider issues assigned to the given user")
)

type createExcluded struct {
	gc          *ghsa.Client
	ic          *issues.Client
	pc          *proxy.Client
	ac          *genai.GeminiClient
	rc          *report.Client
	allowClosed bool
	assignee    string

	isses   map[string]*issues.Issue
	created []string
}

func (createExcluded) name() string { return "create-excluded" }

func (createExcluded) usage() (string, string) {
	const desc = "creates and commits reports for Github issues marked excluded"
	return "", desc
}

func (c *createExcluded) close() error {
	skipped := len(c.isses) - len(c.created)
	if skipped > 0 {
		log.Infof("skipped %d issue(s)", skipped)
	}

	if len(c.created) == 0 {
		log.Infof("no files to commit, exiting")
		return nil
	}

	msg, err := excludedCommitMsg(c.created)
	if err != nil {
		return err
	}

	if *dry {
		log.Outf("create-excluded would commit files:\n\n\t%s\n\nwith message:\n\n%s", strings.Join(c.created, "\n\t"), msg)
		return nil
	}

	if err := gitAdd(c.created...); err != nil {
		return err
	}
	return gitCommit(msg, c.created...)
}

func (c *createExcluded) setup(ctx context.Context) error {
	if *githubToken == "" {
		return fmt.Errorf("githubToken must be provided")
	}
	localRepo, err := gitrepo.Open(ctx, ".")
	if err != nil {
		return err
	}
	rc, err := report.NewClient(localRepo)
	if err != nil {
		return err
	}
	owner, repoName, err := gitrepo.ParseGitHubRepo(*issueRepo)
	if err != nil {
		return err
	}
	var aiClient *genai.GeminiClient
	if *useAI {
		aiClient, err = genai.NewGeminiClient(ctx)
		if err != nil {
			return err
		}
	}

	c.ic = issues.NewClient(ctx, &issues.Config{Owner: owner, Repo: repoName, Token: *githubToken})
	c.gc = ghsa.NewClient(ctx, *githubToken)
	c.pc = proxy.NewDefaultClient()
	c.rc = rc
	c.allowClosed = *closedOk
	c.ac = aiClient
	c.isses = make(map[string]*issues.Issue)

	user := *user
	if user == "" {
		user = os.Getenv("GITHUB_USER")
	}
	c.assignee = user

	return nil
}

func (c *createExcluded) parseArgs(ctx context.Context, args []string) (issNums []string, err error) {
	if len(args) > 0 {
		return nil, fmt.Errorf("expected no arguments")
	}

	stateOption := "open"
	if c.allowClosed {
		stateOption = "all"
	}

	for _, er := range report.ExcludedReasons {
		label := er.ToLabel()
		is, err := c.ic.Issues(ctx, issues.IssuesOptions{Labels: []string{label}, State: stateOption})
		if err != nil {
			return nil, err
		}
		log.Infof("found %d issues with label %s", len(is), label)

		for _, iss := range is {
			if c.rc.HasReport(iss.Number) {
				log.Infof("skipping issue %d which already has a report", iss.Number)
				continue
			}

			if c.assignee != "" && iss.Assignee != c.assignee {
				log.Infof("skipping issue %d (assigned to %s, not %s)", iss.Number, iss.Assignee, c.assignee)
				continue
			}

			n := strconv.Itoa(iss.Number)
			c.isses[n] = iss
			issNums = append(issNums, n)
		}
	}

	return issNums, nil
}

func (c *createExcluded) run(ctx context.Context, issNum string) (err error) {
	iss, ok := c.isses[issNum]
	if !ok {
		return fmt.Errorf("BUG: could not find issue %s (this should have been populated in parseArgs)", issNum)
	}

	r, err := createReport(ctx, iss, c.pc, c.gc, c.ac, c.allowClosed)
	if err != nil {
		return err
	}

	filename, err := writeReport(r)
	if err != nil {
		return err
	}

	c.created = append(c.created, filename)
	return nil
}

func excludedCommitMsg(fs []string) (string, error) {
	var issNums []string
	for _, f := range fs {
		_, _, iss, err := report.ParseFilepath(f)
		if err != nil {
			return "", err
		}
		issNums = append(issNums, fmt.Sprintf("Fixes golang/vulndb#%d", iss))
	}

	return fmt.Sprintf(
		`%s: batch add %d excluded reports

Adds excluded reports:
	- %s

%s`,
		report.ExcludedDir,
		len(fs),
		strings.Join(fs, "\n\t- "),
		strings.Join(issNums, "\n")), nil
}
