package authorization

import (
	"strings"
	"time"

	"git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/api/errs"
	context "github.com/kataras/iris/v12/context"
	"github.com/pascaldekloe/jwt"
)

var (
	SECRET                     = []byte{}
	PREFIX_AUTHORIZATION_TOKEN = "Bearer "
)

type JwtChk func(ctx context.Context, resourceID string, claims *jwt.Claims) (err *errs.Error)

func Handler(resource string, fn JwtChk) func(ctx context.Context) (resp interface{}, err *errs.Error) {

	return func(ctx context.Context) (resp interface{}, err *errs.Error) {
		var (
			claims *jwt.Claims
		)

		if claims, err = ParseToken(ctx.GetHeader("Authorization")); err != nil {
			return
		}

		if err = fn(ctx, resource, claims); err != nil {
			return
		}

		ctx.Next()
		return
	}
}

func ParseToken(token string) (claims *jwt.Claims, err *errs.Error) {
	var (
		_err error
	)

	token = strings.Replace(token, PREFIX_AUTHORIZATION_TOKEN, "", -1)

	if claims, _err = jwt.HMACCheck([]byte(token), SECRET); _err != nil {
		err = errs.Unauthenticated().Details(&errs.Detail{
			Message:      "Login required",
			Location:     "Authorization",
			LocationType: "header",
			Reason:       "InvalidAuthorizationToken",
		})

	} else if !claims.Valid(time.Now()) {
		err = errs.Unauthenticated().Details(&errs.Detail{
			Message:      "Login required",
			Location:     "Authorization",
			LocationType: "header",
			Reason:       "TokenExpired",
		})
	}
	return
}
