// Copyright 2014 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"
	"errors"
	"fmt"
	"net/url"
	"strings"
	"time"

	"cloud.google.com/go/compute/metadata"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google/externalaccount"
	"golang.org/x/oauth2/google/internal/externalaccountauthorizeduser"
	"golang.org/x/oauth2/google/internal/impersonate"
	"golang.org/x/oauth2/jwt"
)

// Endpoint is Google's OAuth 2.0 default endpoint.
var Endpoint = oauth2.Endpoint{
	AuthURL:       "https://accounts.google.com/o/oauth2/auth",
	TokenURL:      "https://oauth2.googleapis.com/token",
	DeviceAuthURL: "https://oauth2.googleapis.com/device/code",
	AuthStyle:     oauth2.AuthStyleInParams,
}

// MTLSTokenURL is Google's OAuth 2.0 default mTLS endpoint.
const MTLSTokenURL = "https://oauth2.mtls.googleapis.com/token"

// JWTTokenURL is Google's OAuth 2.0 token URL to use with the JWT flow.
const JWTTokenURL = "https://oauth2.googleapis.com/token"

// ConfigFromJSON uses a Google Developers Console client_credentials.json
// file to construct a config.
// client_credentials.json can be downloaded from
// https://console.developers.google.com, under "Credentials". Download the Web
// application credentials in the JSON format and provide the contents of the
// file as jsonKey.
func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error) {
	type cred struct {
		ClientID     string   `json:"client_id"`
		ClientSecret string   `json:"client_secret"`
		RedirectURIs []string `json:"redirect_uris"`
		AuthURI      string   `json:"auth_uri"`
		TokenURI     string   `json:"token_uri"`
	}
	var j struct {
		Web       *cred `json:"web"`
		Installed *cred `json:"installed"`
	}
	if err := json.Unmarshal(jsonKey, &j); err != nil {
		return nil, err
	}
	var c *cred
	switch {
	case j.Web != nil:
		c = j.Web
	case j.Installed != nil:
		c = j.Installed
	default:
		return nil, fmt.Errorf("oauth2/google: no credentials found")
	}
	if len(c.RedirectURIs) < 1 {
		return nil, errors.New("oauth2/google: missing redirect URL in the client_credentials.json")
	}
	return &oauth2.Config{
		ClientID:     c.ClientID,
		ClientSecret: c.ClientSecret,
		RedirectURL:  c.RedirectURIs[0],
		Scopes:       scope,
		Endpoint: oauth2.Endpoint{
			AuthURL:  c.AuthURI,
			TokenURL: c.TokenURI,
		},
	}, nil
}

// JWTConfigFromJSON uses a Google Developers service account JSON key file to read
// the credentials that authorize and authenticate the requests.
// Create a service account on "Credentials" for your project at
// https://console.developers.google.com to download a JSON key file.
func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) {
	var f credentialsFile
	if err := json.Unmarshal(jsonKey, &f); err != nil {
		return nil, err
	}
	if f.Type != serviceAccountKey {
		return nil, fmt.Errorf("google: read JWT from JSON credentials: 'type' field is %q (expected %q)", f.Type, serviceAccountKey)
	}
	scope = append([]string(nil), scope...) // copy
	return f.jwtConfig(scope, ""), nil
}

// JSON key file types.
const (
	serviceAccountKey                = "service_account"
	userCredentialsKey               = "authorized_user"
	externalAccountKey               = "external_account"
	externalAccountAuthorizedUserKey = "external_account_authorized_user"
	impersonatedServiceAccount       = "impersonated_service_account"
)

// credentialsFile is the unmarshalled representation of a credentials file.
type credentialsFile struct {
	Type string `json:"type"`

	// Service Account fields
	ClientEmail    string `json:"client_email"`
	PrivateKeyID   string `json:"private_key_id"`
	PrivateKey     string `json:"private_key"`
	AuthURL        string `json:"auth_uri"`
	TokenURL       string `json:"token_uri"`
	ProjectID      string `json:"project_id"`
	UniverseDomain string `json:"universe_domain"`

	// User Credential fields
	// (These typically come from gcloud auth.)
	ClientSecret string `json:"client_secret"`
	ClientID     string `json:"client_id"`
	RefreshToken string `json:"refresh_token"`

	// External Account fields
	Audience                       string                           `json:"audience"`
	SubjectTokenType               string                           `json:"subject_token_type"`
	TokenURLExternal               string                           `json:"token_url"`
	TokenInfoURL                   string                           `json:"token_info_url"`
	ServiceAccountImpersonationURL string                           `json:"service_account_impersonation_url"`
	ServiceAccountImpersonation    serviceAccountImpersonationInfo  `json:"service_account_impersonation"`
	Delegates                      []string                         `json:"delegates"`
	CredentialSource               externalaccount.CredentialSource `json:"credential_source"`
	QuotaProjectID                 string                           `json:"quota_project_id"`
	WorkforcePoolUserProject       string                           `json:"workforce_pool_user_project"`

	// External Account Authorized User fields
	RevokeURL string `json:"revoke_url"`

	// Service account impersonation
	SourceCredentials *credentialsFile `json:"source_credentials"`
}

type serviceAccountImpersonationInfo struct {
	TokenLifetimeSeconds int `json:"token_lifetime_seconds"`
}

func (f *credentialsFile) jwtConfig(scopes []string, subject string) *jwt.Config {
	cfg := &jwt.Config{
		Email:        f.ClientEmail,
		PrivateKey:   []byte(f.PrivateKey),
		PrivateKeyID: f.PrivateKeyID,
		Scopes:       scopes,
		TokenURL:     f.TokenURL,
		Subject:      subject, // This is the user email to impersonate
		Audience:     f.Audience,
	}
	if cfg.TokenURL == "" {
		cfg.TokenURL = JWTTokenURL
	}
	return cfg
}

func (f *credentialsFile) tokenSource(ctx context.Context, params CredentialsParams) (oauth2.TokenSource, error) {
	switch f.Type {
	case serviceAccountKey:
		cfg := f.jwtConfig(params.Scopes, params.Subject)
		return cfg.TokenSource(ctx), nil
	case userCredentialsKey:
		cfg := &oauth2.Config{
			ClientID:     f.ClientID,
			ClientSecret: f.ClientSecret,
			Scopes:       params.Scopes,
			Endpoint: oauth2.Endpoint{
				AuthURL:   f.AuthURL,
				TokenURL:  f.TokenURL,
				AuthStyle: oauth2.AuthStyleInParams,
			},
		}
		if cfg.Endpoint.AuthURL == "" {
			cfg.Endpoint.AuthURL = Endpoint.AuthURL
		}
		if cfg.Endpoint.TokenURL == "" {
			if params.TokenURL != "" {
				cfg.Endpoint.TokenURL = params.TokenURL
			} else {
				cfg.Endpoint.TokenURL = Endpoint.TokenURL
			}
		}
		tok := &oauth2.Token{RefreshToken: f.RefreshToken}
		return cfg.TokenSource(ctx, tok), nil
	case externalAccountKey:
		cfg := &externalaccount.Config{
			Audience:                       f.Audience,
			SubjectTokenType:               f.SubjectTokenType,
			TokenURL:                       f.TokenURLExternal,
			TokenInfoURL:                   f.TokenInfoURL,
			ServiceAccountImpersonationURL: f.ServiceAccountImpersonationURL,
			ServiceAccountImpersonationLifetimeSeconds: f.ServiceAccountImpersonation.TokenLifetimeSeconds,
			ClientSecret:             f.ClientSecret,
			ClientID:                 f.ClientID,
			CredentialSource:         &f.CredentialSource,
			QuotaProjectID:           f.QuotaProjectID,
			Scopes:                   params.Scopes,
			WorkforcePoolUserProject: f.WorkforcePoolUserProject,
		}
		return externalaccount.NewTokenSource(ctx, *cfg)
	case externalAccountAuthorizedUserKey:
		cfg := &externalaccountauthorizeduser.Config{
			Audience:       f.Audience,
			RefreshToken:   f.RefreshToken,
			TokenURL:       f.TokenURLExternal,
			TokenInfoURL:   f.TokenInfoURL,
			ClientID:       f.ClientID,
			ClientSecret:   f.ClientSecret,
			RevokeURL:      f.RevokeURL,
			QuotaProjectID: f.QuotaProjectID,
			Scopes:         params.Scopes,
		}
		return cfg.TokenSource(ctx)
	case impersonatedServiceAccount:
		if f.ServiceAccountImpersonationURL == "" || f.SourceCredentials == nil {
			return nil, errors.New("missing 'source_credentials' field or 'service_account_impersonation_url' in credentials")
		}

		ts, err := f.SourceCredentials.tokenSource(ctx, params)
		if err != nil {
			return nil, err
		}
		imp := impersonate.ImpersonateTokenSource{
			Ctx:       ctx,
			URL:       f.ServiceAccountImpersonationURL,
			Scopes:    params.Scopes,
			Ts:        ts,
			Delegates: f.Delegates,
		}
		return oauth2.ReuseTokenSource(nil, imp), nil
	case "":
		return nil, errors.New("missing 'type' field in credentials")
	default:
		return nil, fmt.Errorf("unknown credential type: %q", f.Type)
	}
}

// ComputeTokenSource returns a token source that fetches access tokens
// from Google Compute Engine (GCE)'s metadata server. It's only valid to use
// this token source if your program is running on a GCE instance.
// If no account is specified, "default" is used.
// If no scopes are specified, a set of default scopes are automatically granted.
// Further information about retrieving access tokens from the GCE metadata
// server can be found at https://cloud.google.com/compute/docs/authentication.
func ComputeTokenSource(account string, scope ...string) oauth2.TokenSource {
	// refresh 3 minutes and 45 seconds early. The shortest MDS cache is currently 4 minutes, so any
	// refreshes earlier are a waste of compute.
	earlyExpirySecs := 225 * time.Second
	return computeTokenSource(account, earlyExpirySecs, scope...)
}

func computeTokenSource(account string, earlyExpiry time.Duration, scope ...string) oauth2.TokenSource {
	return oauth2.ReuseTokenSourceWithExpiry(nil, computeSource{account: account, scopes: scope}, earlyExpiry)
}

type computeSource struct {
	account string
	scopes  []string
}

func (cs computeSource) Token() (*oauth2.Token, error) {
	if !metadata.OnGCE() {
		return nil, errors.New("oauth2/google: can't get a token from the metadata service; not running on GCE")
	}
	acct := cs.account
	if acct == "" {
		acct = "default"
	}
	tokenURI := "instance/service-accounts/" + acct + "/token"
	if len(cs.scopes) > 0 {
		v := url.Values{}
		v.Set("scopes", strings.Join(cs.scopes, ","))
		tokenURI = tokenURI + "?" + v.Encode()
	}
	tokenJSON, err := metadata.Get(tokenURI)
	if err != nil {
		return nil, err
	}
	var res struct {
		AccessToken  string `json:"access_token"`
		ExpiresInSec int    `json:"expires_in"`
		TokenType    string `json:"token_type"`
	}
	err = json.NewDecoder(strings.NewReader(tokenJSON)).Decode(&res)
	if err != nil {
		return nil, fmt.Errorf("oauth2/google: invalid token JSON from metadata: %v", err)
	}
	if res.ExpiresInSec == 0 || res.AccessToken == "" {
		return nil, fmt.Errorf("oauth2/google: incomplete token received from metadata")
	}
	tok := &oauth2.Token{
		AccessToken: res.AccessToken,
		TokenType:   res.TokenType,
		Expiry:      time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second),
	}
	// NOTE(cbro): add hidden metadata about where the token is from.
	// This is needed for detection by client libraries to know that credentials come from the metadata server.
	// This may be removed in a future version of this library.
	return tok.WithExtra(map[string]interface{}{
		"oauth2.google.tokenSource":    "compute-metadata",
		"oauth2.google.serviceAccount": acct,
	}), nil
}
