// Copyright 2017 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.

// The maintq command queries a maintnerd gRPC server.
// This tool is mostly for debugging.
package main

import (
	"context"
	"crypto/tls"
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
	"sort"
	"strings"
	"time"

	"github.com/golang/protobuf/proto"
	"golang.org/x/build/maintner/maintnerd/apipb"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

var (
	server = flag.String("server", "maintner.golang.org:443", "maintnerd server")
)

var (
	mc  apipb.MaintnerServiceClient
	ctx = context.Background()
)

func main() {
	flag.Parse()

	c := credentials.NewTLS(&tls.Config{
		NextProtos:         []string{"h2"},
		InsecureSkipVerify: strings.HasPrefix(*server, "localhost:"),
	})
	opts := []grpc.DialOption{
		grpc.WithDisableRetry(),
		grpc.WithBlock(),
		grpc.WithTimeout(5 * time.Second),
		grpc.WithTransportCredentials(c),
	}

	cc, err := grpc.Dial(*server, opts...)
	if err != nil {
		log.Fatalf("unable to grpc.Dial(%q) = %s", *server, err)
	}
	mc = apipb.NewMaintnerServiceClient(cc)

	cmdFunc := map[string]func(args []string) error{
		"has-ancestor":  callHasAncestor,
		"get-ref":       callGetRef,
		"try-work":      callTryWork,
		"list-releases": callListReleases,
		"get-dashboard": callGetDashboard,
	}
	log.SetFlags(0)
	if flag.NArg() == 0 || cmdFunc[flag.Arg(0)] == nil {
		var cmds []string
		for cmd := range cmdFunc {
			cmds = append(cmds, cmd)
		}
		sort.Strings(cmds)
		log.Fatalf(`Usage: maintq %v ...`, cmds)
	}
	if err := cmdFunc[flag.Arg(0)](flag.Args()[1:]); err != nil {
		log.Fatal(err)
	}
}

func callHasAncestor(args []string) error {
	if len(args) != 2 {
		return errors.New("Usage: maintq has-ancestor <commit> <ancestor>")
	}
	res, err := mc.HasAncestor(ctx, &apipb.HasAncestorRequest{
		Commit:   args[0],
		Ancestor: args[1],
	})
	if err != nil {
		return err
	}
	fmt.Println(res)
	return nil
}

func callGetRef(args []string) error {
	if len(args) != 2 {
		return errors.New("Usage: maintq get-ref <project> <ref>")
	}
	res, err := mc.GetRef(ctx, &apipb.GetRefRequest{
		GerritServer:  "go.googlesource.com",
		GerritProject: args[0],
		Ref:           args[1],
	})
	if err != nil {
		return err
	}
	if res.Value == "" {
		return errors.New("ref not found")
	}
	fmt.Println(res.Value)
	return nil
}

func callTryWork(args []string) error {
	staging := len(args) == 1 && args[0] == "staging"
	if !staging && len(args) > 0 {
		return errors.New(`Usage: maintq try-work ["staging"]  # prod is default`)
	}
	res, err := mc.GoFindTryWork(ctx, &apipb.GoFindTryWorkRequest{ForStaging: staging})
	if err != nil {
		return err
	}
	return printTextProto(res)
}

func callListReleases(args []string) error {
	if len(args) != 0 {
		return errors.New("Usage: maintq list-releases")
	}
	res, err := mc.ListGoReleases(ctx, &apipb.ListGoReleasesRequest{})
	if err != nil {
		return err
	}
	return printTextProto(res)
}

func callGetDashboard(args []string) error {
	req := &apipb.DashboardRequest{}

	fs := flag.NewFlagSet("get-dash-commits", flag.ExitOnError)
	var page int
	fs.IntVar(&page, "page", 0, "0-based page number")
	fs.StringVar(&req.Branch, "branch", "", "branch name; empty means master")
	fs.StringVar(&req.Repo, "repo", "", "repo name; empty means the main repo, otherwise \"golang.org/*\"")
	fs.Parse(args)
	if fs.NArg() != 0 {
		fs.Usage()
		os.Exit(2)
	}

	req.Page = int32(page)

	res, err := mc.GetDashboard(ctx, req)
	if err != nil {
		return err
	}
	return printTextProto(res)
}

func printTextProto(m proto.Message) error {
	tm := proto.TextMarshaler{Compact: false}
	return tm.Marshal(os.Stdout, m)
}
