package online

import (
	"runtime"

	"github.com/gorilla/websocket"
	"github.com/sirupsen/logrus"
	"gogs.daxia.dev/huanan/pkg.daxia.dev/encrypt"
	"gogs.daxia.dev/huanan/pkg.daxia.dev/gzip"
	"nn.daxia.dev/gameproto"
	"nn.daxia.dev/model"
)

type EmitData struct {
	UserID     uint
	NotifyType gameproto.NotifyTypeEnum //通知类型
	Encrypt    bool                     //是否需要加密
	Data       string                   //发送内容
}

const GZipMinLen = 1024

func SendMsg(conn *websocket.Conn, emitData EmitData) error {
	defer func() {
		if err := recover(); err != nil {
			logrus.Error(err)
			buf := make([]byte, 2048*5)
			n := runtime.Stack(buf, false)
			stackInfo := string(buf[:n])
			logrus.Errorf("panic stack info %s", stackInfo)
		}
	}()

	var err error

	data := []byte(emitData.Data)

	tmpData := make([]byte, 0, len(data)+1)
	notifyType := byte(int32(emitData.NotifyType))
	data = append(append(tmpData, notifyType), data...)

	dataType := uint8(gameproto.DataType_DataTypeNormal)

	emitData.Encrypt = false
	if emitData.Encrypt {
		data, _ = encrypt.AesEncrypt(data, model.AESKey)
		dataType = dataType | byte(gameproto.DataType_DataTypeEnc)
	}

	dataLen := len(data)
	if dataLen > GZipMinLen {
		data, err = gzip.GZIPEn([]byte(data))
		if err != nil {
			logrus.Error(err)
			return err
		}

		dataType = dataType | byte(gameproto.DataType_DataTypeGZip)
	}

	sendData := make([]byte, 0, dataLen+1)
	sendData = append(append(sendData, dataType), data...)

	//logData, _ := json.Marshal(emitData.Data)
	//logrus.Infof("write to user %d msg:%s", emitData.UserID, string(logData))

	err = conn.WriteMessage(websocket.BinaryMessage, []byte(sendData))
	if err != nil {
		logrus.Error(err, "_", emitData.UserID, "_", sendData)
		return err
	}

	return nil
}
