// Copyright 2015 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 google

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"runtime"
	"sync"
	"time"

	"cloud.google.com/go/compute/metadata"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/authhandler"
)

const (
	adcSetupURL           = "https://cloud.google.com/docs/authentication/external/set-up-adc"
	defaultUniverseDomain = "googleapis.com"
)

// Credentials holds Google credentials, including "Application Default Credentials".
// For more details, see:
// https://developers.google.com/accounts/docs/application-default-credentials
// Credentials from external accounts (workload identity federation) are used to
// identify a particular application from an on-prem or non-Google Cloud platform
// including Amazon Web Services (AWS), Microsoft Azure or any identity provider
// that supports OpenID Connect (OIDC).
type Credentials struct {
	ProjectID   string // may be empty
	TokenSource oauth2.TokenSource

	// JSON contains the raw bytes from a JSON credentials file.
	// This field may be nil if authentication is provided by the
	// environment and not with a credentials file, e.g. when code is
	// running on Google Cloud Platform.
	JSON []byte

	// UniverseDomainProvider returns the default service domain for a given
	// Cloud universe. Optional.
	//
	// On GCE, UniverseDomainProvider should return the universe domain value
	// from Google Compute Engine (GCE)'s metadata server. See also [The attached service
	// account](https://cloud.google.com/docs/authentication/application-default-credentials#attached-sa).
	// If the GCE metadata server returns a 404 error, the default universe
	// domain value should be returned. If the GCE metadata server returns an
	// error other than 404, the error should be returned.
	UniverseDomainProvider func() (string, error)

	udMu sync.Mutex // guards universeDomain
	// universeDomain is the default service domain for a given Cloud universe.
	universeDomain string
}

// UniverseDomain returns the default service domain for a given Cloud universe.
//
// The default value is "googleapis.com".
//
// Deprecated: Use instead (*Credentials).GetUniverseDomain(), which supports
// obtaining the universe domain when authenticating via the GCE metadata server.
// Unlike GetUniverseDomain, this method, UniverseDomain, will always return the
// default value when authenticating via the GCE metadata server.
// See also [The attached service account](https://cloud.google.com/docs/authentication/application-default-credentials#attached-sa).
func (c *Credentials) UniverseDomain() string {
	if c.universeDomain == "" {
		return defaultUniverseDomain
	}
	return c.universeDomain
}

// GetUniverseDomain returns the default service domain for a given Cloud
// universe. If present, UniverseDomainProvider will be invoked and its return
// value will be cached.
//
// The default value is "googleapis.com".
func (c *Credentials) GetUniverseDomain() (string, error) {
	c.udMu.Lock()
	defer c.udMu.Unlock()
	if c.universeDomain == "" && c.UniverseDomainProvider != nil {
		// On Google Compute Engine, an App Engine standard second generation
		// runtime, or App Engine flexible, use an externally provided function
		// to request the universe domain from the metadata server.
		ud, err := c.UniverseDomainProvider()
		if err != nil {
			return "", err
		}
		c.universeDomain = ud
	}
	// If no UniverseDomainProvider (meaning not on Google Compute Engine), or
	// in case of any (non-error) empty return value from
	// UniverseDomainProvider, set the default universe domain.
	if c.universeDomain == "" {
		c.universeDomain = defaultUniverseDomain
	}
	return c.universeDomain, nil
}

// DefaultCredentials is the old name of Credentials.
//
// Deprecated: use Credentials instead.
type DefaultCredentials = Credentials

// CredentialsParams holds user supplied parameters that are used together
// with a credentials file for building a Credentials object.
type CredentialsParams struct {
	// Scopes is the list OAuth scopes. Required.
	// Example: https://www.googleapis.com/auth/cloud-platform
	Scopes []string

	// Subject is the user email used for domain wide delegation (see
	// https://developers.google.com/identity/protocols/oauth2/service-account#delegatingauthority).
	// Optional.
	Subject string

	// AuthHandler is the AuthorizationHandler used for 3-legged OAuth flow. Required for 3LO flow.
	AuthHandler authhandler.AuthorizationHandler

	// State is a unique string used with AuthHandler. Required for 3LO flow.
	State string

	// PKCE is used to support PKCE flow. Optional for 3LO flow.
	PKCE *authhandler.PKCEParams

	// The OAuth2 TokenURL default override. This value overrides the default TokenURL,
	// unless explicitly specified by the credentials config file. Optional.
	TokenURL string

	// EarlyTokenRefresh is the amount of time before a token expires that a new
	// token will be preemptively fetched. If unset the default value is 10
	// seconds.
	//
	// Note: This option is currently only respected when using credentials
	// fetched from the GCE metadata server.
	EarlyTokenRefresh time.Duration

	// UniverseDomain is the default service domain for a given Cloud universe.
	// Only supported in authentication flows that support universe domains.
	// This value takes precedence over a universe domain explicitly specified
	// in a credentials config file or by the GCE metadata server. Optional.
	UniverseDomain string
}

func (params CredentialsParams) deepCopy() CredentialsParams {
	paramsCopy := params
	paramsCopy.Scopes = make([]string, len(params.Scopes))
	copy(paramsCopy.Scopes, params.Scopes)
	return paramsCopy
}

// DefaultClient returns an HTTP Client that uses the
// DefaultTokenSource to obtain authentication credentials.
func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
	ts, err := DefaultTokenSource(ctx, scope...)
	if err != nil {
		return nil, err
	}
	return oauth2.NewClient(ctx, ts), nil
}

// DefaultTokenSource returns the token source for
// "Application Default Credentials".
// It is a shortcut for FindDefaultCredentials(ctx, scope).TokenSource.
func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSource, error) {
	creds, err := FindDefaultCredentials(ctx, scope...)
	if err != nil {
		return nil, err
	}
	return creds.TokenSource, nil
}

// FindDefaultCredentialsWithParams searches for "Application Default Credentials".
//
// It looks for credentials in the following places,
// preferring the first location found:
//
//  1. A JSON file whose path is specified by the
//     GOOGLE_APPLICATION_CREDENTIALS environment variable.
//     For workload identity federation, refer to
//     https://cloud.google.com/iam/docs/how-to#using-workload-identity-federation on
//     how to generate the JSON configuration file for on-prem/non-Google cloud
//     platforms.
//  2. A JSON file in a location known to the gcloud command-line tool.
//     On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
//     On other systems, $HOME/.config/gcloud/application_default_credentials.json.
//  3. On Google Compute Engine, Google App Engine standard second generation runtimes
//     (>= Go 1.11), and Google App Engine flexible environment, it fetches
//     credentials from the metadata server.
func FindDefaultCredentialsWithParams(ctx context.Context, params CredentialsParams) (*Credentials, error) {
	// Make defensive copy of the slices in params.
	params = params.deepCopy()

	// First, try the environment variable.
	const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
	if filename := os.Getenv(envVar); filename != "" {
		creds, err := readCredentialsFile(ctx, filename, params)
		if err != nil {
			return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err)
		}
		return creds, nil
	}

	// Second, try a well-known file.
	filename := wellKnownFile()
	if b, err := os.ReadFile(filename); err == nil {
		return CredentialsFromJSONWithParams(ctx, b, params)
	}

	// Third, if we're on Google Compute Engine, an App Engine standard second generation runtime,
	// or App Engine flexible, use the metadata server.
	if metadata.OnGCE() {
		id, _ := metadata.ProjectID()
		universeDomainProvider := func() (string, error) {
			universeDomain, err := metadata.Get("universe/universe_domain")
			if err != nil {
				if _, ok := err.(metadata.NotDefinedError); ok {
					// http.StatusNotFound (404)
					return defaultUniverseDomain, nil
				} else {
					return "", err
				}
			}
			return universeDomain, nil
		}
		return &Credentials{
			ProjectID:              id,
			TokenSource:            computeTokenSource("", params.EarlyTokenRefresh, params.Scopes...),
			UniverseDomainProvider: universeDomainProvider,
			universeDomain:         params.UniverseDomain,
		}, nil
	}

	// None are found; return helpful error.
	return nil, fmt.Errorf("google: could not find default credentials. See %v for more information", adcSetupURL)
}

// FindDefaultCredentials invokes FindDefaultCredentialsWithParams with the specified scopes.
func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials, error) {
	var params CredentialsParams
	params.Scopes = scopes
	return FindDefaultCredentialsWithParams(ctx, params)
}

// CredentialsFromJSONWithParams obtains Google credentials from a JSON value. The JSON can
// represent either a Google Developers Console client_credentials.json file (as in ConfigFromJSON),
// a Google Developers service account key file, a gcloud user credentials file (a.k.a. refresh
// token JSON), or the JSON configuration file for workload identity federation in non-Google cloud
// platforms (see https://cloud.google.com/iam/docs/how-to#using-workload-identity-federation).
func CredentialsFromJSONWithParams(ctx context.Context, jsonData []byte, params CredentialsParams) (*Credentials, error) {
	// Make defensive copy of the slices in params.
	params = params.deepCopy()

	// First, attempt to parse jsonData as a Google Developers Console client_credentials.json.
	config, _ := ConfigFromJSON(jsonData, params.Scopes...)
	if config != nil {
		return &Credentials{
			ProjectID:   "",
			TokenSource: authhandler.TokenSourceWithPKCE(ctx, config, params.State, params.AuthHandler, params.PKCE),
			JSON:        jsonData,
		}, nil
	}

	// Otherwise, parse jsonData as one of the other supported credentials files.
	var f credentialsFile
	if err := json.Unmarshal(jsonData, &f); err != nil {
		return nil, err
	}

	universeDomain := f.UniverseDomain
	if params.UniverseDomain != "" {
		universeDomain = params.UniverseDomain
	}
	// Authorized user credentials are only supported in the googleapis.com universe.
	if f.Type == userCredentialsKey {
		universeDomain = defaultUniverseDomain
	}

	ts, err := f.tokenSource(ctx, params)
	if err != nil {
		return nil, err
	}
	ts = newErrWrappingTokenSource(ts)
	return &Credentials{
		ProjectID:      f.ProjectID,
		TokenSource:    ts,
		JSON:           jsonData,
		universeDomain: universeDomain,
	}, nil
}

// CredentialsFromJSON invokes CredentialsFromJSONWithParams with the specified scopes.
func CredentialsFromJSON(ctx context.Context, jsonData []byte, scopes ...string) (*Credentials, error) {
	var params CredentialsParams
	params.Scopes = scopes
	return CredentialsFromJSONWithParams(ctx, jsonData, params)
}

func wellKnownFile() string {
	const f = "application_default_credentials.json"
	if runtime.GOOS == "windows" {
		return filepath.Join(os.Getenv("APPDATA"), "gcloud", f)
	}
	return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", f)
}

func readCredentialsFile(ctx context.Context, filename string, params CredentialsParams) (*Credentials, error) {
	b, err := os.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return CredentialsFromJSONWithParams(ctx, b, params)
}
