package com.genlot.nativesdk.sender;

import android.os.Bundle;

import com.genlot.nativesdk.SystemNI;
import com.genlot.nativesdk.model.CopyLotteryBean;
import com.genlot.nativesdk.model.GameCashTicket;
import com.genlot.nativesdk.model.GameHistoryNumber;
import com.genlot.nativesdk.model.GameRuntimeAttr;
import com.genlot.nativesdk.model.GameTicket;
import com.genlot.nativesdk.model.GameWinBulletin;
import com.genlot.nativesdk.model.HardwareInfo;
import com.genlot.nativesdk.model.OpBean;
import com.genlot.nativesdk.model.ReportBankPayment;
import com.genlot.nativesdk.model.ReportData;
import com.genlot.nativesdk.model.ReportItem;
import com.genlot.nativesdk.model.SoftwareInfo;
import com.genlot.nativesdk.model.WinInfo;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author ZhuYongKang
 * @description 与服务器交易封装类
 * @date 2019/8/15
 */
public class TCPSender {

    private static final String DELIMITER1 = ";";
    private static final String DELIMITER2 = "|";
    private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    private static byte[] resData = new byte[5120];
    private static int[] resLen = new int[2];
    private static String message = "";
    private static final int ERROR_CODE = -55555;
    private static final String ERROR_MESSAGE = "报文解析错误";

    /**
     * APP升级包升级确认
     *
     * @param tradingCode 交易码
     * @param csn         校验号，暂时无用，保留
     * @param listener    回调接口
     */
    public static void t101023UpdateConfirm(int tradingCode, int csn, SenderCallback listener) {
        Runnable runnable = () -> {
            //请求报文
            String reqData = "";
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(),
                    reqData.getBytes().length, resData, resLen);
            Bundle bundle = new Bundle();
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                if (listener != null) {
                    listener.onSenderSuccess(bundle);
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 同步服务器时间
     *
     * @param tradingCode 交易码
     * @param csn         校验号，暂时无用，保留
     * @param listener    回调接口
     */
    public static void t101025SyncTime(int tradingCode, int csn, SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = "";
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                String value = TCPParser.parseNString(new String(resData, 0, resLen[0]), DELIMITER1, 1);
                if (value == null) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    long time = Long.parseLong(value);
                    bundle.putLong(EventToken.EVENT_KEY_RESULT_OBJECT, time);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }


    /**
     * 获取游戏控制参数
     *
     * @param tradingCode 交易码
     * @param csn         校验号，暂时无用，保留
     * @param listener    回调接口
     */
    public static void t101027GetControlInfo(int tradingCode, int csn, SenderCallback listener){
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            String protectMoney = null;
            //请求报文
            String reqData = "";
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                if (!TCPParser.t101027Unpack(new String(resData, 0, resLen[0]), protectMoney)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putString(EventToken.EVENT_KEY_RESULT_OBJECT, protectMoney);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 上传软件版本信息
     *
     * @param tradingCode 交易码
     * @param csn         校验号，暂时无用，保留
     * @param info        软件数据
     * @param listener    回调接口
     */
    public static void t101014UploadSoftwareInfo(int tradingCode, int csn, SoftwareInfo info, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = info.mOSVersion + DELIMITER1 + info.mAppVersion + DELIMITER1 + 0 + DELIMITER1;
            //网络请求
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                if (listener != null) {
                    listener.onSenderSuccess(bundle);
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 上传设备硬件信息
     *
     * @param tradingCode 交易码
     * @param csn         校验号，暂时无用，保留
     * @param info        硬件数据
     * @param listener    回调接口
     */
    public static void t101013UploadHardwareInfo(int tradingCode, int csn, HardwareInfo info, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = info.mModel + DELIMITER1 + info.mBoardType + DELIMITER1 + info.mPrinterType + DELIMITER1
                    + DELIMITER1 + DELIMITER1 + DELIMITER1 + DELIMITER1 + DELIMITER1 + DELIMITER1 + DELIMITER1 + DELIMITER1
                    + DELIMITER1 + DELIMITER1 + DELIMITER1 + DELIMITER1 + DELIMITER1 + DELIMITER1 + info.mDeviceSN + DELIMITER1
                    + DELIMITER1 + info.mCPU + DELIMITER1 + info.mRamSize + DELIMITER1;
            //网络请求
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                if (listener != null) {
                    listener.onSenderSuccess(bundle);
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 查询游戏信息
     *
     * @param tradingCode 交易码
     * @param csn         校验号，暂时无用，保留
     * @param gameID      游戏ID
     * @param listener    回调接口
     */
    public static void t101005QueryGameInfo(int tradingCode, int csn, int[] gameID, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            GameRuntimeAttr[] attr = new GameRuntimeAttr[gameID.length];
            for (int i = 0; i < gameID.length; i++) {
                //请求报文
                String reqData = gameID[i] + DELIMITER1;
                //网络请求
                int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                        resData, resLen);
                if (result != 0) {
                    try {
                        message = new String(resData, 0, resLen[0], "GBK");
                    } catch (UnsupportedEncodingException e) {
                        message = new String(resData, 0, resLen[0]);
                    }
                    if (listener != null) {
                        listener.onSenderFail(result, message);
                    }
                    break;
                } else {
                    //应答报文
                    attr[i] = new GameRuntimeAttr();
                    if (!TCPParser.t101005Unpack(new String(resData, 0, resLen[0]), gameID[i], attr[i])) {
                        if (listener != null) {
                            listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                        }
                        break;
                    } else {
                        if (i == gameID.length - 1) {
                            bundle.putParcelableArray(EventToken.EVENT_KEY_RESULT_OBJECT, attr);
                            if (listener != null) {
                                listener.onSenderSuccess(bundle);
                            }
                        }
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }


    /**
     * 查询游戏流水号
     *
     * @param tradingCode 交易码
     * @param csn         校验号，暂时无用，保留
     * @param gameIDs     游戏ID
     * @param listener    回到接口
     */
    public static void t101022QueryGameSN(int tradingCode, int csn, int[] gameIDs, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            HashMap<Integer, String> gameSNMap = new HashMap<>();
            for (int i = 0; i < gameIDs.length; i++) {
                //请求报文
                String reqData = gameIDs[i] + DELIMITER1;
                int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                        resData, resLen);
                if (result != 0) {
                    try {
                        message = new String(resData, 0, resLen[0], "GBK");
                    } catch (UnsupportedEncodingException e) {
                        message = new String(resData, 0, resLen[0]);
                    }
                    if (listener != null) {
                        listener.onSenderFail(result, message);
                    }
                    break;
                } else {
                    //应答报文
                    if (!TCPParser.t101022Unpack(new String(resData, 0, resLen[0]), gameSNMap)) {
                        if (listener != null) {
                            listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                        }
                        break;
                    } else {
                        if (i == gameIDs.length - 1) {
                            bundle.putSerializable(EventToken.EVENT_KEY_RESULT_OBJECT, gameSNMap);
                            if (listener != null) {
                                listener.onSenderSuccess(bundle);
                            }
                        }
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }


    /**
     * 查询账户余额
     *
     * @param tradingCode 交易码
     * @param csn         校验号，暂时无用，保留
     * @param listener    回调接口
     */
    public static void t101026QueryAccount(int tradingCode, int csn, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = "";
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                double[] value = new double[2];
                if (!TCPParser.t101026Unpack(new String(resData, 0, resLen[0]), value)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putDoubleArray(EventToken.EVENT_KEY_RESULT_OBJECT, value);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 生成投注请求报文
     * @param ticket 票信息
     * @return  请求字符串
     */
    private static String t101200Pack(GameTicket ticket) {
        StringBuilder buffer = new StringBuilder();
        buffer.append(ticket.mGameID);
        buffer.append(DELIMITER1);
        buffer.append(ticket.mGameIssue);
        buffer.append(DELIMITER1);
        buffer.append(ticket.mTicketSN);
        buffer.append(DELIMITER1);
        buffer.append((int) ticket.mBettingMoney);
        buffer.append(DELIMITER1);
        buffer.append(ticket.mFeatureCode);
        buffer.append(DELIMITER1);
        buffer.append(ticket.mMultiIssue);
        buffer.append(DELIMITER1);
        buffer.append(ticket.mMemberID);
        buffer.append(DELIMITER1);
//        票校验码
        buffer.append(DELIMITER1);
//        票区别码
        buffer.append(DELIMITER1);
        buffer.append(ticket.mBets);
        buffer.append(DELIMITER1);
        for (int i = 0; i < ticket.mBets; i++) {
            buffer.append(i + 1);  // 注流水号
            buffer.append(DELIMITER1);
            buffer.append(ticket.mBettingMode[i]);  //投注方式
            buffer.append(DELIMITER1);
            buffer.append(ticket.mPlayType[i]); //玩法
            buffer.append(DELIMITER1);
            buffer.append(ticket.mMultiTimes[i]); //倍数
            buffer.append(DELIMITER1);
            buffer.append(ticket.gameBetDataString[i]); //号码字符串
            buffer.append(DELIMITER1);
        }
        buffer.append(SystemNI.getTerminalCert());//设备认证码
        buffer.append(DELIMITER1);
        return buffer.toString();
    }

    /**
     *  同步投注
     * @param tradingCode 交易码
     * @param csn   校验号，暂时无用，保留
     * @param ticket    票信息
     * @param listener  回调接口
     */
    public static void t101200Betting(int tradingCode, int csn, GameTicket ticket, SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = t101200Pack(ticket);
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            try {
                message = new String(resData, 0, resLen[0], "GBK");
            } catch (UnsupportedEncodingException e) {
                message = new String(resData, 0, resLen[0]);
            }
            if (result != 0) {
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                if (!TCPParser.t101200Unpack(message, ticket)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putParcelable(EventToken.EVENT_KEY_RESULT_OBJECT, ticket);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    private static String t101009Pack(String code) {
        return code +
                DELIMITER1 +
                DELIMITER1 +
                DELIMITER1 +
                DELIMITER1 +
                DELIMITER1 +
                DELIMITER1 +
                SystemNI.getTerminalCert() +
                DELIMITER1;
    }

    /**
     * 兑奖
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param code  交易特征码
     * @param listener  回调接口
     */
    public static void t101009Cash(int tradingCode, int csn, String code, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = t101009Pack(code);
            //网络请求
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            try {
                message = new String(resData, 0, resLen[0], "GBK");
            } catch (UnsupportedEncodingException e) {
                message = new String(resData, 0, resLen[0]);
            }
            if (result != 0) {
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                long value = TCPParser.t101009Unpack(new String(resData, 0, resLen[0]));
                if (0 == value) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putLong(EventToken.EVENT_KEY_RESULT_OBJECT, value);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    private static String t101300Pack(String code) {
        StringBuilder buffer = new StringBuilder();
        //特征码
        buffer.append(code);
        buffer.append(DELIMITER1);
        //GameID
        buffer.append(DELIMITER1);
        //Issue
        buffer.append(DELIMITER1);
        //WagerStationID
        buffer.append(DELIMITER1);
        //TickSN
        buffer.append(DELIMITER1);
        //CheckSum
        buffer.append(DELIMITER1);
        //DigitalCert
        long terminalCert = SystemNI.getTerminalCert();
        buffer.append(terminalCert);
        buffer.append(DELIMITER1);
        return buffer.toString();
    }

    /**
     * 注销
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param code  交易特征码
     * @param listener  回调接口
     */
    public static void t101300Cancel(int tradingCode, int csn, String code, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = t101300Pack(code);
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                long value = TCPParser.t101300Unpack(new String(resData, 0, resLen[0]));
                if (0 == value) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putLong(EventToken.EVENT_KEY_RESULT_OBJECT, value);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    private static String t101999Pack(String code, long sn) {
        StringBuilder buffer = new StringBuilder();
        buffer.append(code);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append("termicert");
        buffer.append(DELIMITER1);
        buffer.append(sn);
        buffer.append(DELIMITER1);
        return buffer.toString();
    }

    /**
     * 冲正
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param code  交易特征码
     * @param listener  回调接口
     */
    public static void t101999SpecialCancel(int tradingCode, int csn, String code, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = t101999Pack(code, 0);
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                long value = TCPParser.t101999Unpack(new String(resData, 0, resLen[0]));
                if (0 == value) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putLong(EventToken.EVENT_KEY_RESULT_OBJECT, value);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    private static String t101007Pack(String code) {
        StringBuilder buffer = new StringBuilder();
        buffer.append(code);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        return buffer.toString();
    }

    /**
     * 票查询
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param code  交易特征码
     * @param listener  回调接口
     */
    public static void t101007QueryTicket(int tradingCode, int csn, String code, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = t101007Pack(code);
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                GameTicket ticket = new GameTicket();
                if (!TCPParser.t101007Unpack(new String(resData, 0, resLen[0]), ticket)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putParcelable(EventToken.EVENT_KEY_RESULT_OBJECT, ticket);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    private static String t101008Pack(String code) {
        StringBuilder buffer = new StringBuilder();
        buffer.append(code);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        return buffer.toString();
    }

    /**
     * 中奖票查询
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param code  交易特征码
     * @param listener  回调接口
     */
    public static void t101008QueryCashTicket(int tradingCode, int csn, String code, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = t101008Pack(code);
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                GameCashTicket caskTicket = new GameCashTicket();
                if (!TCPParser.t101008Unpack(new String(resData, 0, resLen[0]), caskTicket)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putParcelable(EventToken.EVENT_KEY_RESULT_OBJECT, caskTicket);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    private static String t101412Pack(int gameID, String sRange, String eRange) {
        StringBuilder buffer = new StringBuilder();
        buffer.append(gameID);
        buffer.append(DELIMITER1);
        buffer.append(sRange);
        buffer.append(DELIMITER1);
        buffer.append(eRange);
        buffer.append(DELIMITER1);
        buffer.append(-1);
        buffer.append(DELIMITER1);
        return buffer.toString();
    }

    /**
     * 时段报表查询
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param gameID    游戏ID
     * @param sRange    起始时间
     * @param eRange    结束时间
     * @param listener  回调接口
     */
    public static void t101412QueryDailyReport(int tradingCode, int csn, int gameID,
                                               String sRange, String eRange, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = t101412Pack(gameID, sRange, eRange);
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                ReportData reportData = new ReportData();
                if (!TCPParser.t101412Unpack(new String(resData, 0, resLen[0]), reportData)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putParcelable(EventToken.EVENT_KEY_RESULT_OBJECT, reportData);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    private static String t101401Pack(int gameID, String sRange, String eRange) {
        StringBuilder buffer = new StringBuilder();
        buffer.append(gameID);
        buffer.append(DELIMITER1);
        buffer.append(sRange);
        buffer.append(DELIMITER1);
        buffer.append(eRange);
        buffer.append(DELIMITER1);
        buffer.append(-1);
        buffer.append(DELIMITER1);
        return buffer.toString();
    }

    /**
     * 期报表交易查询
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param gameID    游戏ID
     * @param sRange    起始期号
     * @param eRange    结束期号
     * @param listener  回调接口
     */
    public static void t101401QueryIssueReport(int tradingCode, int csn, int gameID,
                                               String sRange, String eRange, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = t101401Pack(gameID, sRange, eRange);
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                ReportItem reportItem = new ReportItem();
                if (!TCPParser.t101401Unpack(new String(resData, 0, resLen[0]), reportItem)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putParcelable(EventToken.EVENT_KEY_RESULT_OBJECT, reportItem);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 时段报表查询
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param sRange    起始时间 单位秒
     * @param eRange    结束时间 单位秒
     * @param listener  回调接口
     */
    public static void t101404QueryBankReport(int tradingCode, int csn, String sRange, String eRange,
                                              final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = sRange + DELIMITER1 + eRange + DELIMITER1;
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                ReportBankPayment bankPayment = new ReportBankPayment();
                if (!TCPParser.t101404Unpack(new String(resData, 0, resLen[0]), bankPayment)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putParcelable(EventToken.EVENT_KEY_RESULT_OBJECT, bankPayment);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 本机中奖信息
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param gameID    游戏ID
     * @param issue     期号
     * @param listener  回调接口
     */
    public static void t101451QueryStationWinInfo(int tradingCode, int csn, int gameID,
                                                  long issue, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = gameID + DELIMITER1 + issue + DELIMITER1;
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                ArrayList<WinInfo> infos = new ArrayList<>();
                if (!TCPParser.t101451Unpack(new String(resData, 0, resLen[0]),infos)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putParcelableArrayList(EventToken.EVENT_KEY_RESULT_OBJECT, infos);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 增加工号
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param userID    操作员ID
     * @param listener  回调接口
     */
    public static void t101040AddUser(int tradingCode, int csn, int userID, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = userID + DELIMITER1 + 2 + DELIMITER1
                    + "Operator" + DELIMITER1;
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                if (listener != null) {
                    listener.onSenderSuccess(bundle);
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 删除工号
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param userID    操作员ID
     * @param listener  回调接口
     */
    public static void t101041DelUser(int tradingCode, int csn, int userID, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = userID + DELIMITER1;
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                if (listener != null) {
                    listener.onSenderSuccess(bundle);
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 修改密码
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param userID    操作员ID
     * @param oldP      原始密码
     * @param newP      新密码
     * @param listener  回调接口
     */
    public static void t101042ChangeUserPassword(int tradingCode, int csn, int userID, String oldP, String newP, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = userID + DELIMITER1 + oldP + DELIMITER1
                    + newP + DELIMITER1 + "1" + DELIMITER1;
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                if (listener != null) {
                    listener.onSenderSuccess(bundle);
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 查询工号列表
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param listener  回调接口
     */
    public static void t101043QueryUserList(int tradingCode, int csn, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = "";
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            try {
                message = new String(resData, 0, resLen[0], "GBK");
            } catch (UnsupportedEncodingException e) {
                message = new String(resData, 0, resLen[0]);
            }
            if (result != 0) {
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                ArrayList<OpBean> opList = new ArrayList<>();
                if (!TCPParser.t101043Unpack(message, opList)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putParcelableArrayList(EventToken.EVENT_KEY_RESULT_OBJECT, opList);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 获取新期（短周期）
     * @param tradingCode   交易码
     * @param csn   校验号，暂时无用，保留
     * @param gameID    游戏ID
     * @param listener  回调接口
     */
    public static void t101453QueryNewIssue(int tradingCode, int csn, int gameID, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = gameID + DELIMITER1;
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                GameRuntimeAttr attr = new GameRuntimeAttr();
                if (!TCPParser.t101453Unpack(new String(resData, 0, resLen[0]), attr)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putParcelable(EventToken.EVENT_KEY_RESULT_OBJECT, attr);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 获取开奖号码
     * @param tradingCode   交易码
     * @param csn   保留参数
     * @param gameID    游戏ID
     * @param issue     期号
     * @param listener  回调接口
     */
    public static void t101454QueryWinNumber(int tradingCode, int csn, int gameID, long issue, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = gameID + DELIMITER1 + issue + DELIMITER1;
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                ArrayList<String> winNums = new ArrayList<>();
                if (!TCPParser.t101454Unpack(new String(resData, 0, resLen[0]), gameID, issue, winNums)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putStringArrayList(EventToken.EVENT_KEY_RESULT_OBJECT, winNums);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 获取开奖公告
     * @param tradingCode   交易码
     * @param csn       保留参数
     * @param gameID    游戏ID
     * @param issue     期号
     * @param listener  回调接口
     */
    public static void t101455QueryWinBulletin(int tradingCode, int csn, int gameID, long issue, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = gameID + DELIMITER1 + issue + DELIMITER1;
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                GameWinBulletin winBulletin = new GameWinBulletin();
                if (!TCPParser.t101455Unpack(new String(resData, 0, resLen[0]), gameID, issue, winBulletin)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putParcelable(EventToken.EVENT_KEY_RESULT_OBJECT, winBulletin);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 查询历史开奖号码
     * @param tradingCode   tradingCode
     * @param csn   csn
     * @param gameID    gameID
     * @param listener  listener
     */
    public static void t101459QueryHistoryNumber(int tradingCode, int csn, int gameID, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = gameID + DELIMITER1;
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                ArrayList<GameHistoryNumber> historyNumbers = new ArrayList<>();
                if (!TCPParser.t101459Unpack(new String(resData, 0, resLen[0]), historyNumbers)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putParcelableArrayList(EventToken.EVENT_KEY_RESULT_OBJECT, historyNumbers);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    /**
     * 取JACKPOT实时累计奖励
     * @param tradingCode 交易码
     * @param csn   保留参数
     * @param listener  回调接口
     */
    public static void t101462RealTimeJK(int tradingCode, int csn, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = "";
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                String str = TCPParser.t101462Unpack(new String(resData, 0, resLen[0]));
                if (str == null) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putString(EventToken.EVENT_KEY_RESULT_OBJECT, str);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }

    private static String t103007Pack(String featureCode) {
        StringBuilder buffer = new StringBuilder();
        buffer.append(featureCode);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        buffer.append(DELIMITER1);
        return buffer.toString();
    }

    /**
     * 复制票
     * @param tradingCode   交易码
     * @param csn   保留接口
     * @param featureCode   特征码
     * @param listener  回调接口
     */
    public static void t103007CopyLottery(int tradingCode, int csn, String featureCode, final SenderCallback listener) {
        Runnable runnable = () -> {
            Bundle bundle = new Bundle();
            //请求报文
            String reqData = t103007Pack(featureCode);
            int result = SystemNI.callGateway(tradingCode, reqData.getBytes(), reqData.getBytes().length,
                    resData, resLen);
            if (result != 0) {
                try {
                    message = new String(resData, 0, resLen[0], "GBK");
                } catch (UnsupportedEncodingException e) {
                    message = new String(resData, 0, resLen[0]);
                }
                if (listener != null) {
                    listener.onSenderFail(result, message);
                }
            } else {
                //应答报文
                CopyLotteryBean bean = new CopyLotteryBean();
                if (!TCPParser.t103007Unpack(new String(resData, 0, resLen[0]), bean)) {
                    if (listener != null) {
                        listener.onSenderFail(ERROR_CODE, ERROR_MESSAGE);
                    }
                } else {
                    bundle.putParcelable(EventToken.EVENT_KEY_RESULT_OBJECT, bean);
                    if (listener != null) {
                        listener.onSenderSuccess(bundle);
                    }
                }
            }
        };
        cachedThreadPool.execute(runnable);
    }


    public interface SenderCallback {
        void onSenderSuccess(Bundle bundle);

        void onSenderFail(int code, String message);
    }
}
