package token

import (
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/pingcap/errors"
	"github.com/tidbcloud/pkgv2/auth/auth0"
)

var ErrTokenNotFound = errors.NotFoundf("token not found")

func GetToken(c *gin.Context) (string, error) {
	header := c.GetHeader("authorization")
	if header == "" {
		/*
		   since HTTP/2 use a lower case header, HTTP/1.x header is case-insensitive,
		   but generally we use a Authorization header in HTTP/1.x
		   LINK:
		   https://tools.ietf.org/html/rfc7540#section-8.1.2
		   https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
		*/
		header = c.GetHeader("Authorization")
	}

	if header == "" {
		return "", ErrTokenNotFound
	}

	tokenSlice := strings.Split(header, " ")
	if len(tokenSlice) != 2 || strings.ToLower(tokenSlice[0]) != "bearer" {
		return "", ErrTokenNotFound
	}

	return tokenSlice[1], nil
}

func InitAuth0TokenValidator(centralAuth0 auth0.Conf) (*Validator, error) {
	jwks, err := auth0.GetJWKS(centralAuth0.Domain)
	if err != nil {
		return nil, errors.Trace(err)
	}

	tokenValidator := auth0.NewRawTokenValidator().
		RegisterAuth(auth0.AuthValidatorIDCentral, centralAuth0, jwks)

	return NewValidator(tokenValidator), nil
}
