// issues_helper is a simple command-line application for the monorail issue tracker.
//
// It can be used in a few modes, for example:
// issues_helper --alsologtostderr comment 5255 "Spectacular flooring"
// issues_helper --alsologtostderr query "is:open label:FromSkiaPerf"
package main

import (
	"flag"
	"fmt"

	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/issues"
	"go.skia.org/infra/go/sklog"
)

var (
	tracker issues.IssueTracker

	status      = flag.String("status", "New", "The status of the newly created issue")
	summary     = flag.String("summary", "", "The summary/title of the newly created issue")
	description = flag.String("description", "", "The description of the newly created issue")
	owner       = flag.String("owner", "", "The email address of the issue's owner")
	cc          = common.NewMultiStringFlag("cc", nil, fmt.Sprintf("The email addresses to cc to this issue."))
	labels      = common.NewMultiStringFlag("labels", nil, fmt.Sprintf(`The labels to add to this issue.  Common labels are "Type-Defect","Priority-Medium","Restrict-View-Google"`))
	component   = flag.String("component", "", "Component name under which to file the issue.")
	project     = flag.String("project", "", "Project ID under which to file the issue.")
)

func main() {
	common.Init()
	args := flag.Args()
	if len(args) < 1 {
		fmt.Println("Usage: issues_helper <mode> [OPTIONS]")
		return
	}
	mode := args[0]

	ts, err := auth.NewDefaultTokenSource(true, "https://www.googleapis.com/auth/userinfo.email")
	if err != nil {
		sklog.Fatalf("Unable to create token source: %s", err)
	}
	if *project == "" {
		*project = issues.PROJECT_SKIA
	}
	client := httputils.DefaultClientConfig().WithTokenSource(ts).With2xxOnly().Client()
	tracker = issues.NewMonorailIssueTracker(client, *project)
	switch mode {
	case "query":
		if len(args) < 2 {
			fmt.Println("Usage: issues_helper query <query_string>")
			return
		}
		handleQuery(args[1:])
	case "comment":
		if len(args) < 4 {
			fmt.Println("Usage: issues_helper comment <issue_id> <comment_string>")
			return
		}
		handleComment(args[1:])
	case "create":
		if len(args) != 1 || !checkCreateFlags() {
			fmt.Println("Usage: issues_helper [--options=foo,bar] create")
			fmt.Println("Required flags: --status, --summary, --description")
			fmt.Println("Optional flags: --owner, --labels, --cc")
			return
		}
		handleCreate()
	}
}

func handleQuery(args []string) {
	query := args[0]
	iss, err := tracker.FromQuery(query)
	if err != nil {
		sklog.Errorf("Failed to retrieve issues: %s\n", err)
		return
	}
	fmt.Printf("Found: %d\n", len(iss))
	for _, issue := range iss {
		sklog.Infof("%20d %10s %s\n", issue.ID, issue.State, issue.Title)
	}
}

func handleComment(args []string) {
	id := args[0]
	comment := issues.CommentRequest{
		Content: args[1],
	}
	if err := tracker.AddComment(id, comment); err != nil {
		sklog.Errorf("Failed to add comment: %s\n", err)
		return
	}
}

func handleCreate() {
	ccPeople := make([]issues.MonorailPerson, 0)
	for _, p := range *cc {
		ccPeople = append(ccPeople, issues.MonorailPerson{
			Name: p,
		})
	}
	req := issues.IssueRequest{
		Status: *status,
		Owner: issues.MonorailPerson{
			Name: *owner,
		},
		CC:          ccPeople,
		Labels:      *labels,
		Summary:     *summary,
		Description: *description,
		Components:  []string{*component},
	}
	if err := tracker.AddIssue(req); err != nil {
		sklog.Errorf("Failed to add issue: %s", err)
	}
}

func checkCreateFlags() bool {
	return *status != "" && *summary != "" && *description != ""
}
