// Copyright 2021 The Go 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 bootstrap

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/storage"

	"golang.org/x/oauth2/google"

	"google.golang.org/api/option"
)

type AuthOption int

const (
	AuthNone AuthOption = iota
	AuthAppDefault
	NumAuthOptions
)

var authOptString = [NumAuthOptions]string{
	"none",
	"app-default",
}

func (a *AuthOption) String() string {
	return authOptString[*a]
}

func (a *AuthOption) Set(input string) error {
	for i := range authOptString {
		if authOptString[i] == input {
			*a = AuthOption(i)
			return nil
		}
	}
	return fmt.Errorf("unrecognized authentication option: %s", input)
}

func UploadArchive(r io.Reader, bucket, version string, auth AuthOption, force, public bool) error {
	ctx := context.Background()
	var opts []option.ClientOption
	switch auth {
	case AuthAppDefault:
		creds, err := google.FindDefaultCredentials(ctx, storage.ScopeReadWrite)
		if err != nil {
			return err
		}
		opts = append(opts, option.WithCredentials(creds))
	case AuthNone:
		return fmt.Errorf("authentication required for upload")
	default:
		return fmt.Errorf("unknown authentication method")
	}
	client, err := storage.NewClient(ctx, opts...)
	if err != nil {
		return err
	}
	o := client.Bucket(bucket).Object(VersionArchiveName(version))
	if _, err := o.Attrs(ctx); err != nil && err != storage.ErrObjectNotExist {
		return fmt.Errorf("checking if object exists: %v", err)
	} else if err == nil && !force {
		return fmt.Errorf("assets object already exists for version %s", version)
	}

	// Write the archive to GCS.
	wc := o.NewWriter(ctx)
	if _, err = io.Copy(wc, r); err != nil {
		return err
	}
	if err := wc.Close(); err != nil {
		return err
	}

	if public {
		// Make the archive public.
		acl := o.ACL()
		return acl.Set(ctx, storage.AllUsers, storage.RoleReader)
	}
	return nil
}

func DownloadArchive(w io.Writer, bucket, version string, auth AuthOption) error {
	ctx := context.Background()
	opts := []option.ClientOption{option.WithScopes(storage.ScopeReadOnly)}
	switch auth {
	case AuthAppDefault:
		creds, err := google.FindDefaultCredentials(ctx, storage.ScopeReadOnly)
		if err != nil {
			return err
		}
		opts = append(opts, option.WithCredentials(creds))
	case AuthNone:
		opts = append(opts, option.WithoutAuthentication())
	default:
		return fmt.Errorf("unknown authentication method")
	}
	client, err := storage.NewClient(ctx, opts...)
	if err != nil {
		return err
	}
	rc, err := client.Bucket(bucket).Object(VersionArchiveName(version)).NewReader(ctx)
	if err != nil {
		return err
	}
	if _, err = io.Copy(w, rc); err != nil {
		return err
	}
	return rc.Close()
}
