// Copyright 2022 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 secret

import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"strings"

	"cloud.google.com/go/compute/metadata"
	secretmanager "cloud.google.com/go/secretmanager/apiv1"
	secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1"
)

// FlagResolver contains the dependencies necessary to resolve a Secret flag.
type FlagResolver struct {
	Context          context.Context
	Client           secretClient
	DefaultProjectID string
}

const secretSuffix = "[ specify `secret:[project name/]<secret name>` to read from Secret Manager ]"

// Flag declares a string flag on set that will be resolved using r.
func (r *FlagResolver) Flag(set *flag.FlagSet, name string, usage string) *string {
	var value string
	suffixedUsage := usage + "\n" + secretSuffix
	set.Func(name, suffixedUsage, func(flagValue string) error {
		var err error
		value, err = r.resolveSecret(flagValue)
		return err
	})
	return &value
}

func (r *FlagResolver) resolveSecret(flagValue string) (string, error) {
	if r.Client == nil || r.Context == nil {
		return "", fmt.Errorf("secret resolver was not initialized")
	}
	if !strings.HasPrefix(flagValue, "secret:") {
		return flagValue, nil
	}

	secretName := strings.TrimPrefix(flagValue, "secret:")
	projectID := r.DefaultProjectID
	if parts := strings.SplitN(secretName, "/", 2); len(parts) == 2 {
		projectID, secretName = parts[0], parts[1]
	}
	if projectID == "" {
		return "", fmt.Errorf("missing project ID: none specified in %q, and no default set (not on GCP?)", secretName)
	}
	result, err := r.Client.AccessSecretVersion(r.Context, &secretmanagerpb.AccessSecretVersionRequest{
		Name: buildNamePath(projectID, secretName, "latest"),
	})
	if err != nil {
		return "", fmt.Errorf("reading secret %q from project %v failed: %v", secretName, projectID, err)
	}
	return string(result.Payload.GetData()), nil
}

// JSONVarFlag declares a flag on set that behaves like Flag and then
// json.Unmarshals the resulting string into value.
func (r *FlagResolver) JSONVarFlag(set *flag.FlagSet, value interface{}, name string, usage string) {
	suffixedUsage := usage + "\n" + fmt.Sprintf("A JSON representation of a %T.", value) + "\n" + secretSuffix
	set.Func(name, suffixedUsage, func(flagValue string) error {
		stringValue, err := r.resolveSecret(flagValue)
		if err != nil {
			return err
		}
		return json.Unmarshal([]byte(stringValue), value)
	})
}

// DefaultResolver is the FlagResolver used by the convenience functions.
var DefaultResolver FlagResolver

// Flag declares a string flag on flag.CommandLine that supports Secret Manager
// resolution for values like "secret:<secret name>". InitFlagSupport must be
// called before flag.Parse.
func Flag(name string, usage string) *string {
	return DefaultResolver.Flag(flag.CommandLine, name, usage)
}

// JSONVarFlag declares a flag on flag.CommandLine that behaves like Flag
// and then json.Unmarshals the resulting string into value.
func JSONVarFlag(value interface{}, name string, usage string) {
	DefaultResolver.JSONVarFlag(flag.CommandLine, value, name, usage)
}

// InitFlagSupport initializes the dependencies for flags declared with Flag.
func InitFlagSupport(ctx context.Context) error {
	client, err := secretmanager.NewClient(ctx)
	if err != nil {
		return err
	}
	DefaultResolver = FlagResolver{
		Context: ctx,
		Client:  client,
	}
	if metadata.OnGCE() {
		projectID, err := metadata.ProjectID()
		if err != nil {
			return err
		}
		DefaultResolver.DefaultProjectID = projectID
	}

	return nil
}
