package jwt

import (
	
	
	
	
)

// DecodePaddingAllowed will switch the codec used for decoding JWTs respectively. Note that the JWS RFC7515
// states that the tokens will utilize a Base64url encoding with no padding. Unfortunately, some implementations
// of JWT are producing non-standard tokens, and thus require support for decoding. Note that this is a global
// variable, and updating it will change the behavior on a package level, and is also NOT go-routine safe.
// To use the non-recommended decoding, set this boolean to `true` prior to using this package.
var DecodePaddingAllowed bool

// DecodeStrict will switch the codec used for decoding JWTs into strict mode.
// In this mode, the decoder requires that trailing padding bits are zero, as described in RFC 4648 section 3.5.
// Note that this is a global variable, and updating it will change the behavior on a package level, and is also NOT go-routine safe.
// To use strict decoding, set this boolean to `true` prior to using this package.
var DecodeStrict bool

// TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time).
// You can override it to use another time value.  This is useful for testing or if your
// server uses a different time zone than your tokens.
var TimeFunc = time.Now

// Keyfunc will be used by the Parse methods as a callback function to supply
// the key for verification.  The function receives the parsed,
// but unverified Token.  This allows you to use properties in the
// Header of the token (such as `kid`) to identify which key to use.
type Keyfunc func(*Token) (interface{}, error)

// Token represents a JWT Token.  Different fields will be used depending on whether you're
// creating or parsing/verifying a token.
type Token struct {
	Raw       string                 // The raw token.  Populated when you Parse a token
	Method    SigningMethod          // The signing method used or to be used
	Header    map[string]interface{} // The first segment of the token
	Claims    Claims                 // The second segment of the token
	Signature string                 // The third segment of the token.  Populated when you Parse a token
	Valid     bool                   // Is the token valid?  Populated when you Parse/Verify a token
}

// New creates a new Token with the specified signing method and an empty map of claims.
func ( SigningMethod) *Token {
	return NewWithClaims(, MapClaims{})
}

// NewWithClaims creates a new Token with the specified signing method and claims.
func ( SigningMethod,  Claims) *Token {
	return &Token{
		Header: map[string]interface{}{
			"typ": "JWT",
			"alg": .Alg(),
		},
		Claims: ,
		Method: ,
	}
}

// SignedString creates and returns a complete, signed JWT.
// The token is signed using the SigningMethod specified in the token.
func ( *Token) ( interface{}) (string, error) {
	var ,  string
	var  error
	if ,  = .SigningString();  != nil {
		return "", 
	}
	if ,  = .Method.Sign(, );  != nil {
		return "", 
	}
	return strings.Join([]string{, }, "."), nil
}

// SigningString generates the signing string.  This is the
// most expensive part of the whole deal.  Unless you
// need this for something special, just go straight for
// the SignedString.
func ( *Token) () (string, error) {
	var  error
	var  []byte

	if ,  = json.Marshal(.Header);  != nil {
		return "", 
	}
	 := EncodeSegment()

	if ,  = json.Marshal(.Claims);  != nil {
		return "", 
	}
	 := EncodeSegment()

	return strings.Join([]string{, }, "."), nil
}

// Parse parses, validates, verifies the signature and returns the parsed token.
// keyFunc will receive the parsed token and should return the cryptographic key
// for verifying the signature.
// The caller is strongly encouraged to set the WithValidMethods option to
// validate the 'alg' claim in the token matches the expected algorithm.
// For more details about the importance of validating the 'alg' claim,
// see https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/
func ( string,  Keyfunc,  ...ParserOption) (*Token, error) {
	return NewParser(...).Parse(, )
}

// ParseWithClaims is a shortcut for NewParser().ParseWithClaims().
//
// Note: If you provide a custom claim implementation that embeds one of the standard claims (such as RegisteredClaims),
// make sure that a) you either embed a non-pointer version of the claims or b) if you are using a pointer, allocate the
// proper memory for it before passing in the overall claims, otherwise you might run into a panic.
func ( string,  Claims,  Keyfunc,  ...ParserOption) (*Token, error) {
	return NewParser(...).ParseWithClaims(, , )
}

// EncodeSegment encodes a JWT specific base64url encoding with padding stripped
//
// Deprecated: In a future release, we will demote this function to a non-exported function, since it
// should only be used internally
func ( []byte) string {
	return base64.RawURLEncoding.EncodeToString()
}

// DecodeSegment decodes a JWT specific base64url encoding with padding stripped
//
// Deprecated: In a future release, we will demote this function to a non-exported function, since it
// should only be used internally
func ( string) ([]byte, error) {
	 := base64.RawURLEncoding

	if DecodePaddingAllowed {
		if  := len() % 4;  > 0 {
			 += strings.Repeat("=", 4-)
		}
		 = base64.URLEncoding
	}

	if DecodeStrict {
		 = .Strict()
	}
	return .DecodeString()
}