// 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"
	"log"
	"path/filepath"
	"strings"

	"github.com/google/subcommands"
	"go.chromium.org/luci/auth/client/authcli"
	"go.chromium.org/luci/hardcoded/chromeinfra"
	"go.fuchsia.dev/infra/artifacts"
	"go.fuchsia.dev/infra/buildbucket"
	"golang.org/x/sync/errgroup"
)

type artifactsClient interface {
	GetBuildDir(bucket, build string) artifacts.Directory
}

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

	// Whether source should be relative to the Cloud Storage bucket's root directory.
	// If false, source will be relative to the target build's Cloud Storage directory.
	fromRoot bool
}

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 file or directory to download from the build's Cloud Storage directory")
	f.StringVar(&cmd.dest, "dst", "", "The local path to write the artifact(s) to")
	f.BoolVar(&cmd.fromRoot, "root", false, "Whether src is relative to the root directory of the Cloud Storage bucket."+
		"If false, src will be taken as a relative path to the build-specific directory under the Cloud Storage bucket.")
}

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, opts)
	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 {
	// If cmd.source is an archive, it will have an extension like .tgz or .tar.gz.
	// Otherwise, we assume it to be a directory in the artifacts bucket.
	// getStorageBucket will retrieve the appropriate bucket based on whether the source
	// is an archive or not.
	fetchArchive := filepath.Ext(cmd.source) != ""
	bucket, err := getStorageBucket(ctx, buildsCli, cmd.build, fetchArchive)
	if err != nil {
		return err
	}

	build := cmd.build
	if cmd.fromRoot {
		build = ""
	}
	dir := artifactsCli.GetBuildDir(bucket, build)
	objs, err := dir.List(ctx, cmd.source)
	if err != nil {
		return err
	}
	var eg errgroup.Group
	for _, obj := range objs {
		obj := obj
		eg.Go(func() error {
			var dest string
			if obj == cmd.source {
				// cmd.source is a single artifact. Copy it directly to cmd.dest.
				dest = cmd.dest
			} else {
				// obj is a path relative to the dir with cmd.source as its prefix.
				// We want to get the relative path to cmd.source so that we can write
				// it to the same relative path to cmd.dest.
				relPath := strings.TrimPrefix(obj, cmd.source+"/")
				dest = filepath.Join(cmd.dest, relPath)
			}
			if err := dir.CopyFile(ctx, obj, dest); err != nil {
				return err
			}
			return nil
		})
	}
	return eg.Wait()
}
