// Package vaultgcsblob registers the vaultgs:// URL scheme with gocloud.dev.
package vaultgcsblob

import (
	"context"
	"flag"
	"fmt"
	"net/url"
	"sync"

	"gocloud.dev/blob"
	"gocloud.dev/blob/gcsblob"
	"gocloud.dev/gcp"
	"hg.lukegb.com/lukegb/depot/go/vault/vaultgcp"
)

var (
	vaultAddr        = flag.String("vault_addr", "unix:///run/tokend/sock", "Address of vault agent, or tokend.")
	vaultTokenSource = flag.String("vault_token_source", "", "Token source for retrieving OAuth token. e.g. gcp/roleset/binary-cache-deployer/token")
)

type lazyOpener struct {
	init   sync.Once
	opener *gcsblob.URLOpener
	err    error
}

func (o *lazyOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket, error) {
	o.init.Do(func() {
		c, err := gcp.NewHTTPClient(gcp.DefaultTransport(), vaultgcp.TokenSource(ctx, *vaultAddr, *vaultTokenSource))
		if err != nil {
			o.err = fmt.Errorf("creating GCP HTTP client using Vault token: %w", err)
			return
		}
		o.opener = &gcsblob.URLOpener{
			Client: c,
		}
	})
	if o.err != nil {
		return nil, o.err
	}
	return o.opener.OpenBucketURL(ctx, u)
}

func init() {
	blob.DefaultURLMux().RegisterBucket("vaultgs", new(lazyOpener))
}