// 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
	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.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, buildsClient buildbucketpb.BuildsClient) (int64, error) {
	res, err := buildsClient.SearchBuilds(ctx, &buildbucketpb.SearchBuildsRequest{
		Predicate: &buildbucketpb.BuildPredicate{
			Builder: builderID,
			Status:  buildbucketpb.Status_SUCCESS,
			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, 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)
	}
}
