/**
 * tsrpc连接管理
 */

import { HttpClient as HttpClient_Browser, WsClient as WsClient_Browser } from 'tsrpc-browser';
import { HttpClient as HttpClient_Miniapp, WsClient as WsClient_Miniapp } from 'tsrpc-miniapp';
import { serviceProto as ServiceProtoRoom, ServiceType, ServiceType as ServiceTypeRoom } from "../shared/serviceProto";
import { GameServerConfig } from './GameServerConfig';
import { ShareConfig } from './ShareConfig';
import { Security } from './Security';
import { BaseResponse } from '../shared/base';


/** TSRPC网络模块 */
export class TsrpcNet {

    constructor() {
    }

    /** 创建连接登录服务器 Http 客户端 */
    createLoginServer(serverUrl: string) {
        let hcGate = new (cc.sys.platform == cc.sys.WECHAT_GAME ? HttpClient_Miniapp : HttpClient_Browser)(ServiceProtoRoom, {
            server: serverUrl,
            json: ShareConfig.json,
            logger: console
        });
        this.flowClientApi(hcGate);
        this.flowAuth(hcGate);
        return hcGate;
    }


    /**
     *  创建连接房间服务器 Websocket 客户端
     * @param serverUrl 服务器地址
     * @returns WsClient
     */
    createWscRoom(serverUrl: string) {
        // 创建客户端与房间服务器的 WebSocket 连接
        let wscRoom = new (cc.sys.platform == cc.sys.WECHAT_GAME ? WsClient_Miniapp : WsClient_Browser)(ServiceProtoRoom, {
            // server: serverUrl + "?" + Date.now(),
            server: serverUrl,
            heartbeat: {
                interval: GameServerConfig.heartbeat_interval,
                timeout: GameServerConfig.heartbeat_timeout
            },
            json: ShareConfig.json,
            logger: console,
            // logMsg: true,
        });

        this.flowClientApi(wscRoom);
        // this.flowAuth(wscRoom);

        return wscRoom;
    }

    /** HTTP 客户端协议数据加密、解密 */
    private flowClientApi(hc: any) {
        if (!ShareConfig.security) return;

        hc.flows.preSendDataFlow.push(v => {
            if (v.data instanceof Uint8Array) {
                v.data = Security.encrypt(v.data);
            }
            return v;
        });

        // 在处理接收到的数据之前，通常要进行加密/解密
        hc.flows.preRecvDataFlow.push(v => {
            if (v.data instanceof Uint8Array) {
                v.data = Security.decrypt(v.data);
            }
            return v;
        });
    }

    /** 帐号登录令牌验证是否逻辑（帐号中加入登录令牌，服务器通过令牌解析玩家数据，如果存在就是已登录） */
    private flowAuth(client: any) {              // HttpClient WsClient
        // 执行 callApi 之前协议中插入登录令牌
        client.flows.preCallApiFlow.push(v => {
            // 请求前插入登录令牌
            let ssoToken = cc.sys.localStorage.getItem('SSO_TOKEN');
            if (ssoToken) {
                v.req.__ssoToken = ssoToken;
            }
            return v;
        })

        // 将 callApi 的结果返回给调用方之后将登录令牌存到本地（收到协议时将登录令牌存到本地）
        client.flows.postApiReturnFlow.push(v => {
            if (v.return.isSucc) {
                let res = v.return.res as BaseResponse;

                // 请求成功后刷新登录令牌
                // if (res.__ssoToken !== undefined) {
                //     cc.sys.localStorage.setItem('SSO_TOKEN', res.__ssoToken);
                // }
            }
            // 登录令牌过期时删除客户端登录令牌（可跳转到登录界面）
            else if (v.return.err.code === 'NEED_LOGIN') {
                cc.sys.localStorage.setItem('SSO_TOKEN', '');
            }
            return v;
        });
    }



}