package cn.muchinfo.rma.business.account.adapter

import cn.muchinfo.rma.business.global.MessageHeadModel
import cn.muchinfo.rma.global.GlobalDataCollection
import cn.muchinfo.rma.netcore.crypto.SHA256Encrypt
import cn.muchinfo.rma.netcore.packet.Packet50
import cn.muchinfo.rma.protobuf.funcode.FunCode
import cn.muchinfo.rma.protobuf.protoclasses.SystemMI1
import java.io.ByteArrayOutputStream
import java.lang.Exception
import java.util.*

/**
 * 账户相关装解箱
 */
class AccountAdapter {
    companion object {
        /**
         * 构建登录请求报文
         * @return Packet50 登录请求报文
         */
        fun buildLoginReqPacket(loginID: String, password: String): Packet50 {
            val funCode = FunCode.LoginReq

            val builder = SystemMI1.LoginReq.newBuilder()
            builder.loginID = loginID.toLong()
            val encrypt = SHA256Encrypt()
            builder.loginPWD =
                encrypt.getEncryptString(encrypt.encrypt(String.format("%s%s", loginID, password)))
                    .toLowerCase(Locale.ROOT)
            builder.loginType = 0
            builder.clientType = 3
            builder.version = "5.0.0.0"
            val uuid = UUID.randomUUID()
            builder.guid = uuid.toString()
            // deviceID主要用于标记设备唯一标识，由于无法获取MAC或IP信息，故使用UUID
            builder.deviceID = uuid.toString()

            builder.setHeader(MessageHeadModel.getHead(funCode, 0, 0, 0, 0))
            val arrayOutputStream = ByteArrayOutputStream();
            builder.build().writeTo(arrayOutputStream)

            return Packet50(funCode, arrayOutputStream.toByteArray())
        }

        /**
         * 分析登录报文
         * @param packet50 Packet50 登录回复报文
         * @return Triple<Boolean, Error?, SystemMI1.LoginRsp?> 是否成功，错误，LoginRsp
         */
        fun analysisLoginRsp(packet50: Packet50): Triple<Boolean, Error?, SystemMI1.LoginRsp?> {
            return try {
                val loginRsp = SystemMI1.LoginRsp.parseFrom(packet50.content)
                if (loginRsp.retCode == 0) {
                    // 登录成功
                    Triple(true, null, loginRsp)
                } else {
                    // 登录失败
                    Triple(false, Error(loginRsp.retCode.toString()), null)
                }
            } catch (e: Exception) {
                // 登录失败
                Triple(false, Error("装箱失败"), null)
            }
        }

        /**
         * 构建Token检验请求报文
         * @param loginID Long
         * @param token String
         * @return Packet50
         */
        fun buildTokenCheckReqPacket(loginID: Long, token: String): Packet50 {
            val funCode = FunCode.TokenCheckReq

            val builder = SystemMI1.TokenCheckReq.newBuilder()
            builder.loginID = loginID
            builder.token = token
            builder.systemTime = Date().time + GlobalDataCollection.instance?.timeStamp!!

            val loginRsp = GlobalDataCollection.instance?.loginRsp
            builder.setHeader(MessageHeadModel.getHead(funCode, loginRsp?.userID ?: 0, 0, 0, 0))
            val arrayOutputStream = ByteArrayOutputStream();
            builder.build().writeTo(arrayOutputStream)

            return Packet50(funCode, arrayOutputStream.toByteArray())
        }

        /**
         * 分析Token检验回复报文
         * @param packet50 Packet50 Token检验回复报文
         * @return Pair<Boolean, Error?> 是否成功，错误
         */
        fun analysisTokenCheckRsp(packet50: Packet50): Pair<Boolean, Error?> {
            return try {
                val tokenCheckRsp = SystemMI1.TokenCheckRsp.parseFrom(packet50.content)
                if (tokenCheckRsp.retCode == 0) {
                    // Token检验成功
                    Pair(true, null)
                } else {
                    // Token检验失败
                    Pair(false, Error(tokenCheckRsp.retDesc))
                }
            } catch (e: Exception) {
                // 装箱失败
                Pair(false, Error("装箱失败"))
            }
        }
    }
}