package auth0

import (
	"errors"
	"strings"

	jwtmiddleware "github.com/auth0/go-jwt-middleware"
	"github.com/form3tech-oss/jwt-go"
)

// TODO(chenfei): replace 'github.com/form3tech-oss/jwt-go' by 'github.com/golang-jwt/jwt' when
// go-jwt-middleware v2 be released: https://github.com/auth0/go-jwt-middleware/issues/86

// NewJwtMiddleware return a handler to check the client auth
func NewJwtMiddleware(auth0Domain, auth0Audience string) (*jwtmiddleware.JWTMiddleware, error) {
	jwks, err := GetJWKS(auth0Domain)
	if err != nil {
		return nil, err
	}

	jwtMiddleware := jwtmiddleware.New(jwtmiddleware.Options{
		ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
			// Verify 'aud' claim
			checkAud := token.Claims.(jwt.MapClaims).VerifyAudience(auth0Audience, false)
			if !checkAud {
				return token, errors.New("invalid audience")
			}
			// Verify 'iss' claim
			iss := "https://" + auth0Domain + "/"
			checkIss := token.Claims.(jwt.MapClaims).VerifyIssuer(iss, false)
			if !checkIss {
				return token, errors.New("invalid issuer")
			}

			cert, err := MakePemCert(token, jwks)
			if err != nil {
				panic(err.Error())
			}

			return jwt.ParseRSAPublicKeyFromPEM([]byte(cert))
		},
		SigningMethod: jwt.SigningMethodRS256,
	})
	return jwtMiddleware, nil
}

func IsAuth0UserExistError(err error) bool {
	return strings.Contains(err.Error(), "The user already exists")
}

const (
	UserPasswordErrMsg = `The password must contain three character categories among the following:
	<ul>
	<li> Uppercase characters (A-Z)</li>
	<li> Lowercase characters (a-z)</li>
	<li> Digits (0-9) </li>
	</ul>	
	`
)

func IsAuth0PasswordStrengthError(err error) bool {
	return strings.Contains(err.Error(), "PasswordStrengthError")
}
