package logic

//复用websocket连接标识
import (
	"encoding/json"
	"fmt"
	"fusenapi/constants"
	"fusenapi/utils/encryption_decryption"
	"github.com/zeromicro/go-zero/core/logx"
)

// 复用连接处理器
type reuseConnProcessor struct {
}

// 处理分发到这里的数据
func (r *reuseConnProcessor) allocationMessage(w *wsConnectItem, data []byte) {
	logx.Info("收到请求恢复上次连接标识数据:", string(data))
	var wid string
	if err := json.Unmarshal(data, &wid); err != nil {
		logx.Error(" invalid format of wid :", wid)
		w.incomeDataFormatErrResponse("invalid format of wid")
		return
	}
	//解密
	decryptionWid, err := encryption_decryption.CBCDecrypt(wid)
	if err != nil {
		w.reuseLastConnErrResponse("invalid wid")
		return
	}
	lendecryptionWid := len(decryptionWid)
	//合成client后缀,不是同个后缀的不能复用
	userPart := getUserJoinPart(w.userId, w.guestId, w.userAgent)
	lenUserPart := len(userPart)
	if lendecryptionWid <= lenUserPart {
		w.reuseLastConnErrResponse("length of client id is to short")
		return
	}
	//尾部不同不能复用
	if decryptionWid[lendecryptionWid-lenUserPart:] != userPart {
		w.reuseLastConnErrResponse("the client id is not belong to you before")
		return
	}
	//存在是不能给他申请重新绑定
	if v, ok := mapConnPool.Load(wid); ok {
		obj, ok := v.(wsConnectItem)
		if !ok {
			w.reuseLastConnErrResponse("连接断言失败")
			logx.Error("连接断言失败")
			return
		}
		//是当前自己占用(无需处理)
		if obj.uniqueId == w.uniqueId {
			rsp := w.respondDataFormat(constants.WEBSOCKET_CONNECT_SUCCESS, wid)
			w.sendToOutChan(rsp)
			return
		} else {
			w.reuseLastConnErrResponse("the wid is used by other people")
			return
		}
	}
	//重新绑定
	logx.Info("开始重新绑定websocket连接标识")
	oldUniqueId := w.uniqueId
	w.uniqueId = wid
	mapConnPool.Store(wid, *w)
	//删除用户id级别之前的索引
	deleteUserConnPoolElement(w.userId, w.guestId, oldUniqueId)
	//添加用户id级别索引
	createUserConnPoolElement(w.userId, w.guestId, wid)
	rsp := w.respondDataFormat(constants.WEBSOCKET_CONNECT_SUCCESS, wid)
	w.sendToOutChan(rsp)
	logx.Info("重新绑定websocket连接标识成功")
}

// 获取用户拼接部分(复用标识用到)
func getUserJoinPart(userId, guestId int64, userAgent string) string {
	return fmt.Sprintf("|_%d_%d_|_%s_|", userId, guestId, userAgent)
}