// 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"

	"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 NewStorageWriter(bucket, version string, auth AuthOption, force bool) (*storage.Writer, error) {
	ctx := context.Background()
	var opts []option.ClientOption
	switch auth {
	case AuthAppDefault:
		creds, err := google.FindDefaultCredentials(ctx, storage.ScopeReadWrite)
		if err != nil {
			return nil, err
		}
		opts = append(opts, option.WithCredentials(creds))
	case AuthNone:
		return nil, fmt.Errorf("authentication required for upload")
	default:
		return nil, fmt.Errorf("unknown authentication method")
	}
	client, err := storage.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	o := client.Bucket(bucket).Object(VersionArchiveName(version))
	if _, err := o.Attrs(ctx); err != nil && err != storage.ErrObjectNotExist {
		return nil, fmt.Errorf("checking if object exists: %v", err)
	} else if err == nil && !force {
		return nil, fmt.Errorf("assets object already exists for version %s", version)
	}
	return o.NewWriter(ctx), nil
}

func NewStorageReader(bucket, version string, auth AuthOption) (*storage.Reader, 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 nil, err
		}
		opts = append(opts, option.WithCredentials(creds))
	case AuthNone:
		opts = append(opts, option.WithoutAuthentication())
	default:
		return nil, fmt.Errorf("unknown authentication method")
	}
	client, err := storage.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	return client.Bucket(bucket).Object(VersionArchiveName(version)).NewReader(ctx)
}
