package jwt

import (
	
	
)

// MapClaims is a claims type that uses the map[string]interface{} for JSON
// decoding. This is the default claims type if you don't supply one
type MapClaims map[string]interface{}

// GetExpirationTime implements the Claims interface.
func ( MapClaims) () (*NumericDate, error) {
	return .parseNumericDate("exp")
}

// GetNotBefore implements the Claims interface.
func ( MapClaims) () (*NumericDate, error) {
	return .parseNumericDate("nbf")
}

// GetIssuedAt implements the Claims interface.
func ( MapClaims) () (*NumericDate, error) {
	return .parseNumericDate("iat")
}

// GetAudience implements the Claims interface.
func ( MapClaims) () (ClaimStrings, error) {
	return .parseClaimsString("aud")
}

// GetIssuer implements the Claims interface.
func ( MapClaims) () (string, error) {
	return .parseString("iss")
}

// GetSubject implements the Claims interface.
func ( MapClaims) () (string, error) {
	return .parseString("sub")
}

// parseNumericDate tries to parse a key in the map claims type as a number
// date. This will succeed, if the underlying type is either a [float64] or a
// [json.Number]. Otherwise, nil will be returned.
func ( MapClaims) ( string) (*NumericDate, error) {
	,  := []
	if ! {
		return nil, nil
	}

	switch exp := .(type) {
	case float64:
		if  == 0 {
			return nil, nil
		}

		return newNumericDateFromSeconds(), nil
	case json.Number:
		,  := .Float64()

		return newNumericDateFromSeconds(), nil
	}

	return nil, newError(fmt.Sprintf("%s is invalid", ), ErrInvalidType)
}

// parseClaimsString tries to parse a key in the map claims type as a
// [ClaimsStrings] type, which can either be a string or an array of string.
func ( MapClaims) ( string) (ClaimStrings, error) {
	var  []string
	switch v := [].(type) {
	case string:
		 = append(, )
	case []string:
		 = 
	case []interface{}:
		for ,  := range  {
			,  := .(string)
			if ! {
				return nil, newError(fmt.Sprintf("%s is invalid", ), ErrInvalidType)
			}
			 = append(, )
		}
	}

	return , nil
}

// parseString tries to parse a key in the map claims type as a [string] type.
// If the key does not exist, an empty string is returned. If the key has the
// wrong type, an error is returned.
func ( MapClaims) ( string) (string, error) {
	var (
		  bool
		 interface{}
		 string
	)
	,  = []
	if ! {
		return "", nil
	}

	,  = .(string)
	if ! {
		return "", newError(fmt.Sprintf("%s is invalid", ), ErrInvalidType)
	}

	return , nil
}