package main

import (
	"../mod"
	"../nt"
	"../rpc"
	"../utils"
	"./pb"
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"strconv"
	"strings"
)

var (
	ErrFailedFindUserAgent = errors.New("failed to find agent by user")
	ErrFailedFindLobby     = errors.New("failed to find agent by id")
	ErrRedisLuaError       = errors.New("redis lua return invalid value")
)

func LoadRedisLua() error {
	var err error
	sha_wallet_transfer, err = nt.Rdb.ScriptLoad(wallet_transfer).Result()
	return err
}

// 创建 error 映射，返回映射的条目
func BuildErrors() int {
	for k, v := range pb.Ec_name {
		E[pb.Ec(k)] = errors.New(v)
	}
	E[pb.Ec_SUCCESS] = nil

	return len(E)
}

func CheckContentType(ct string) error {
	ct_t := strings.ToLower(ct)
	if ct_t != "application/json" {
		return E[pb.Ec_PARAMS_]
	}
	return nil
}

func CheckToken(token string) error {
	should := utils.Md5([]byte(AgentName + APIKey))
	if should != token {
		return E[pb.Ec_TOKEN]
	}
	return nil
}

func CheckContext(c *gin.Context) error {

	ct := c.Request.Header.Get("Content-Type")
	err := CheckContentType(ct)
	if nil != err {
		return err
	}

	agentName_ := c.Param("agentName")
	if len(agentName_) > 0 {
		if agentName_ != AgentName {
			return E[pb.Ec_AGENT_NOT_FOUND]
		}
	} else {
		return E[pb.Ec_AGENT_NOT_FOUND]
	}

	return nil
}

func ConvertBalance(balance int64) float64 {
	return float64(balance) / 100
}

func ConvertAmount(amount float64) int64 {
	return decimal.NewFromFloat(amount).Mul(decimal.NewFromFloat(100)).IntPart()
}

func GetUserAgent(guid uint64) (string, error) {
	agent, err := mod.GetUserAgent(guid)
	if nil != err {
		return "", err
	}
	for _, conf := range nt.DynConf.Lobbies {
		if conf.Id == agent {
			return "http://" + conf.RpcAddr + "/rpc", nil
		}
	}
	return "", ErrFailedFindUserAgent
}

// 通知玩家金币变动
// @guid
// @delta
//
// 重新定义指令 wallet_transfer
// 参数 guid, delta
func RpcNotifyBalanceChange(guid uint64, delta, newBalance int64) error {
	addr, err := GetUserAgent(guid)
	if nil != err {
		return err
	}
	args := rpc.RpcArgs{
		Cmd: "wallet_transfer",
		Params: utils.H{
			"guid":       guid,
			"delta":      delta,
			"newBalance": newBalance,
		},
	}
	res := rpc.RpcResult{}
	return rpc.RpcRequest(addr, &args, &res)
}

// 修改金币并增加注单记录
func UpdateSerialStatus(guid uint64, delta int64, ticketId int64, serial string, val interface{}) ([]interface{}, error) {
	keys := []string{
		mod.KUserInfo(guid),
		mod.KTradeStatus(AgentName, ticketId),
		serial,
		mod.KTradeTicketMap(AgentName),
		strconv.FormatInt(ticketId, 10),
	}
	args := []interface{}{
		delta,
		val,
	}
	r, err := nt.Rdb.EvalSha(sha_wallet_transfer, keys, args...).Result()
	if nil != err {
		return nil, err
	}
	res, ok := r.([]interface{})
	if !ok {
		return nil, ErrRedisLuaError
	}
	return res, nil
}
