// Copyright 2019 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

import (
	"context"
	"flag"
	"fmt"
	"io"
	"log"
	"os"

	"fuchsia.googlesource.com/tools/artifacts"
	"fuchsia.googlesource.com/tools/buildbucket"
	"github.com/google/subcommands"
	"go.chromium.org/luci/auth/client/authcli"
	"go.chromium.org/luci/hardcoded/chromeinfra"
)

type CopyCommand struct {
	authFlags authcli.Flags

	build string
	// The remote filepath with the target build's Cloud Storage directory.
	source string

	// The local path to write the artifact to.
	dest string
}

func (*CopyCommand) Name() string {
	return "cp"
}

func (*CopyCommand) Usage() string {
	return "cp [flags...]"
}

func (*CopyCommand) Synopsis() string {
	return "fetches an artifact produced by a Fuchsia builder"
}

func (cmd *CopyCommand) SetFlags(f *flag.FlagSet) {
	cmd.authFlags.Register(flag.CommandLine, chromeinfra.DefaultAuthOptions())
	f.StringVar(&cmd.build, "build", "", "the ID of the build that produced the artifacts")
	f.StringVar(&cmd.source, "src", "", "The artifact to download from the build's Cloud Storage directory")
	f.StringVar(&cmd.dest, "dst", "", "The local path to write the artifact to")
}

func (cmd *CopyCommand) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
	if err := cmd.validateAndExecute(ctx); err != nil {
		log.Println(err)
		return subcommands.ExitFailure
	}
	return subcommands.ExitSuccess
}

func (cmd *CopyCommand) validateAndExecute(ctx context.Context) error {
	opts, err := cmd.authFlags.Options()
	if err != nil {
		return err
	}

	if cmd.source == "" {
		return fmt.Errorf("missing -src")
	}

	if cmd.dest == "" {
		return fmt.Errorf("missing -dst")
	}

	buildsCli, err := buildbucket.NewBuildsClient(ctx, buildbucket.DefaultHost, opts)
	if err != nil {
		return fmt.Errorf("failed to create builds client: %v", err)
	}

	artifactsCli, err := artifacts.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("failed to create artifacts client: %v", err)
	}

	return cmd.execute(ctx, buildsCli, artifactsCli)
}

func (cmd *CopyCommand) execute(ctx context.Context, buildsCli buildsClient, artifactsCli artifactsClient) error {
	bucket, err := getStorageBucket(ctx, buildsCli, cmd.build)
	if err != nil {
		return err
	}

	input, err := artifactsCli.Open(ctx, bucket, cmd.build, cmd.source)
	if err != nil {
		return err
	}

	output, err := os.Create(cmd.dest)
	if err != nil {
		return err
	}

	_, err = io.Copy(output, input)
	return err
}

// artifactsClient fetches artifacts produced by Fuchsia builds.
type artifactsClient interface {
	List(ctx context.Context, bucket, build string) ([]string, error)
	Open(ctx context.Context, bucket, build, path string) (io.Reader, error)
}
