// 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{
				&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)
	}
}
