package service

import (
	"context"

	"git.apinb.com/bsm-sdk/core/crypto/encipher"
	"git.apinb.com/bsm-sdk/core/errcode"
	"git.apinb.com/bsm-sdk/core/types"
	"git.apinb.com/bsm-sdk/core/utils"
	"google.golang.org/grpc/metadata"
)

// 解析Context中MetaData的数据
type ParseOptions struct {
	RoleValue        string // 判断角色的值
	MustPrivateAllow bool   // 是否只允许私有IP访问
}

func ParseMetaCtx(ctx context.Context, opts *ParseOptions) (*types.JwtClaims, error) {
	// 解析metada中的信息并验证
	md, ok := metadata.FromIncomingContext(ctx)
	if !ok {
		return nil, errcode.ErrJWTAuthNotFound
	}

	var Authorizations []string = md.Get("authorization")
	if len(Authorizations) == 0 || Authorizations[0] == "" {
		return nil, errcode.ErrJWTAuthNotFound
	}

	claims, err := encipher.ParseTokenAes(Authorizations[0])
	if err != nil {
		return nil, err
	}

	if opts != nil {
		if !checkRole(claims, "role", opts.RoleValue) {
			return nil, errcode.ErrPermissionDenied
		}
		if opts.MustPrivateAllow {
			if utils.IsPublicIP(claims.Client) {
				return nil, errcode.ErrPermissionDenied
			}
		}
	}

	return claims, nil

}

func checkRole(claims *types.JwtClaims, roleKey, roleValue string) bool {
	if roleValue == "" {
		return true
	}
	if role, exists := claims.Extend[roleKey]; !exists || role != roleValue {
		return false
	} else {
		return true
	}
}