package utils

import (
	"gd_management_gateway/errors"
	"strconv"
	"time"

	"gd_management_gateway/common.in/cache"
	"gd_management_gateway/common.in/config"

	"github.com/dgrijalva/jwt-go"
)

type UtimesClaims struct {
	Jti string `json:"jti"`
	jwt.StandardClaims
}

type UserClaims struct {
	Uid      int64  `json:"uid"`
	Level    int64  `json:"level"`
	UserName string `json:"user_name"`
	jwt.StandardClaims
}

type UtimesIssuer int

const (
	UserJWTKey = "be2bc479a23b6161c229b0a27359d868"
)

func ProductToken(uid, level int64, userName string) (string, error) {
	expired, _ := config.Conf.Cgi.Gateway.TokenExpired.Int64()
	claims := UserClaims{
		uid,
		level,
		userName,
		jwt.StandardClaims{
			ExpiresAt: time.Now().Unix() + expired, //3600*2, //过期时间
			Subject:   strconv.FormatInt(uid, 10),  //uid
			IssuedAt:  time.Now().Unix(),           //生成时间
			NotBefore: time.Now().Unix(),
		},
	}

	plain := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	return plain.SignedString([]byte(UserJWTKey))
}

func checkTokenFromRedisAndReproduct(tokenString string, token *jwt.Token) error {
	if clams, ok := token.Claims.(*UserClaims); ok {
		RedisSetEx(tokenString, "")
		err := RedisGet(tokenString)
		if err != nil {
			ProductToken(clams.Uid, clams.Level, clams.UserName)
		}
		return nil
	} else {
		return errors.UserTokenillegality
	}

}

func GetUserNameFromToken(tokenString string) string {
	parser := &jwt.Parser{SkipClaimsValidation:true}
	token, _ :=  parser.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(UserJWTKey), nil
	})

	//token, _ := jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
	//	return []byte(UserJWTKey), nil
	//})

	if clams, ok := token.Claims.(*UserClaims); ok {
		return clams.UserName
	} else {
		return ""
	}
	return ""
}
func ParseToken(tokenString string) (int64, int64, error) {
	token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(UserJWTKey), nil
	})
	rvalue := ""
	if !token.Valid {
		rvalue, _ = cache.Redis.Get(tokenString)
		if rvalue != tokenString {
			return 0, 0, errors.UserTokenExpire
		}
	}
	if err != nil && rvalue != tokenString {
		return 0, 0, errors.UserTokenillegality
	}

	if clams, ok := token.Claims.(*UserClaims); ok {
		expired, _ := config.Conf.Cgi.Gateway.TokenExpired.Int64()
		cache.Redis.SetEx(tokenString, expired, tokenString)
		return clams.Uid, clams.Level, nil
	} else {
		return 0, 0, errors.UserTokenillegality
	}
}
