// Copyright 2018 The Fuchsia 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

// TODO(nmulcahey): Implement general Search RPC support in the buildbucket
// CLI and remove this + LKGS

import (
	"context"
	"flag"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"

	"go.chromium.org/luci/auth"
	"go.chromium.org/luci/buildbucket/proto"
	"go.chromium.org/luci/grpc/prpc"

	"go.chromium.org/luci/auth/client/authcli"
	"go.chromium.org/luci/hardcoded/chromeinfra"
)

var (
	host        string
	builderID   string
	buildSet    string
	buildStatus int
	output      string
	// LUCI flags used to parse command-line authentication options.
	authFlags authcli.Flags
)

func init() {
	flag.StringVar(&host, "host", "cr-buildbucket.appspot.com", "the buildbucket host to use (default is cr-buildbucket.appspot.com)")
	flag.StringVar(&builderID, "builder-id", "", "name of the builders to use as a reference (e.g. fuchsia/ci/garnet-x64)")
	flag.StringVar(&buildSet, "build-set", "", "a unique buildset id in buildbucket (e.g. commit/gitiles/fuchsia.googlesource.com/topaz/+/e3127e0bd6d57da7a5959ee70eb0a396590e6d53)")
	flag.IntVar(&buildStatus, "build-status", int(buildbucketpb.Status_SUCCESS), "expected build status (default is 12, SUCCESS). see https://godoc.org/go.chromium.org/luci/buildbucket/proto#Status")
	flag.StringVar(&output, "output-file", "", "name of the file to write snapshot to (default is stdout)")

	authFlags = authcli.Flags{}
	authFlags.Register(flag.CommandLine, chromeinfra.DefaultAuthOptions())
}

// praseBuilderID parses a builder ID of the form "fuchsia/ci/garnet-x64".
func parseBuilderID(builderID string) (*buildbucketpb.BuilderID, error) {
	components := strings.SplitN(builderID, "/", 3)
	if len(components) != 3 {
		return nil, fmt.Errorf("failed to parse builder ID")
	}
	return &buildbucketpb.BuilderID{
		Project: components[0],
		Bucket:  components[1],
		Builder: components[2],
	}, nil
}

func getBuildIDForBuilderAndBuildSet(ctx context.Context, host, buildSetID string, builderID *buildbucketpb.BuilderID, buildStatus int32, buildsClient buildbucketpb.BuildsClient) (int64, error) {
	res, err := buildsClient.SearchBuilds(ctx, &buildbucketpb.SearchBuildsRequest{
		Predicate: &buildbucketpb.BuildPredicate{
			Builder: builderID,
			Status:  buildbucketpb.Status(buildStatus),
			Tags: []*buildbucketpb.StringPair{
				{
					Key:   "buildset",
					Value: buildSetID,
				},
			},
		},
	})
	if err != nil {
		return -1, err
	}
	if len(res.Builds) == 0 {
		return -1, fmt.Errorf("No builds returned")
	}
	return res.Builds[0].Id, nil
}

func main() {
	flag.Parse()

	if builderID == "" || buildSet == "" {
		flag.PrintDefaults()
		return
	}

	id, err := parseBuilderID(builderID)
	if err != nil {
		log.Fatalf(err.Error())
	}

	opts, err := authFlags.Options()
	if err != nil {
		log.Fatalf(err.Error())
	}

	ctx := context.Background()
	authenticator := auth.NewAuthenticator(ctx, auth.OptionalLogin, opts)
	client, err := authenticator.Client()
	if err != nil {
		log.Fatalf(err.Error())
	}

	buildsClient := buildbucketpb.NewBuildsPRPCClient(&prpc.Client{
		C:    client,
		Host: host,
	})

	buildID, err := getBuildIDForBuilderAndBuildSet(ctx, host, buildSet, id, int32(buildStatus), buildsClient)
	if err != nil {
		log.Fatalf(err.Error())
	}

	var outputFile *os.File
	if output == "" {
		outputFile = os.Stdout
	} else {
		outputFile, err = os.Create(output)
		if err != nil {
			log.Fatalf(err.Error())
		}
		defer outputFile.Close()
	}
	_, err = outputFile.Write([]byte(strconv.FormatInt(buildID, 10)))
	if err != nil {
		log.Fatalf("writing output: %v", err)
	}
}
