#include <stdlib.h>
#include <stdio.h>
#include <jni.h>
#include <unistd.h>
#include <sys/stat.h>
#include "gttoolkitext.h"
#include "gt.h"
#include "gterror.h"
#include "gtmem.h"
#include "gtftnetwork.h"

GtFTNetwork::GtFTNetwork():_networkTimeout(45)
{
    _networkSocket = -1;
    _networkStatus = 0;
    _networkTransSN = 0;
    memset(_errorMsg, 0, sizeof(_errorMsg));
    _errorCode = 0;
}

GtFTNetwork::~GtFTNetwork()
{

}

/************************************************************
*功能：连接文件下载服务器
*输入：serverIP=服务器IP
*输入：port=服务器端口
*输出：无
*返回：!=0错误
*/
int GtFTNetwork::connectFileServer(char *serverIP, unsigned short port)
{
    int socketFd = -1;
    int result = 0;

    if(_networkSocket > -1)
    {
        close(_networkSocket);
        _networkSocket = -1;
    }
    result = GtToolkitExt::tcpSocket(&socketFd);
    if(result != 0)
    {
        return result;
    }
    result = GtToolkitExt::tcpConnect(socketFd, serverIP, port, 10);
    if(result != 0)
    {
        close(socketFd);
        return result;
    }
    _networkSocket = socketFd;
    return 0;
}

/************************************************************
*功能：关闭文件下载链路
*输入：无
*输出：无
*返回：无
*/
void GtFTNetwork::closeFileServer()
{
    if(_networkSocket > -1)
    {
        close(_networkSocket);
        _networkSocket = -1;
    }
}

/************************************************************
*功能：网络数据转换
*输入：transCode=交易码
*输入：inBuf=请求数据
*输入：inLen=请求数据长度
*输入：outBuf=应答数据
*输入：outLen=应答数据长度
*输出：无
*返回：无
*/
int GtFTNetwork::callFTNetwork(unsigned long tradingCode, char *inBuf, int inLen, char *outBuf, int *outLen)
{
    int result = 0;
    int length = 0;
    char tmpBuf[1024];
    unsigned long uniqueSN = 0;
    unsigned long receiveCode = 0;
    unsigned long receiveSN = 0;
    stTerminal terminal;
    unsigned char data[BLOCK_MTU];
    char u8Data[BLOCK_MTU];
    int u8Length = 0;

    if(_networkSocket <= -1)
    {
        return GtError::ERROR_FILE_SERVER_NOT_CONNECT;
    }
    memset(&terminal, 0, sizeof(stTerminal));
    result = GtMem::instance()->getMemTerminal(&terminal);
    if(result != 0)
    {
        return result;
    }
    uniqueSN = ++_networkTransSN;
    memset(data, 0, sizeof(data));
    length = sprintf((char *)&data[2], "%lu%c%d%c%lu%c%s%c%d%c", tradingCode, Gt::_delimiter1,
        0, Gt::_delimiter1,
        uniqueSN, Gt::_delimiter1,
        terminal.strTerminalID, Gt::_delimiter1,
        0, Gt::_delimiter1);
    memcpy(&data[length + 2], inBuf, inLen);
    length += inLen;
    data[0] = length/256;
    data[1] = length%256;
    result = GtToolkitExt::writeN(_networkSocket, data, length + 2);
    if(result != 0)
    {
        GtToolkitExt::logError(__FILE__, __LINE__, "[%d]发送文件下载请求错误", result);
        return result;
    }
    if(999102 != tradingCode && 999104 != tradingCode)
    {
        GtToolkitExt::logInfo(__FILE__, __LINE__, "[-->]%s", &data[2]);
    }
    //接收应答
    while(1)
    {
        memset(data, 0, sizeof(data));
        result = GtToolkitExt::readN(_networkSocket, data, 2, _networkTimeout);
        if(result != 0)
        {
            GtToolkitExt::logError(__FILE__, __LINE__, "[%d]接收文件下载数据错误", result);
            return result;
        }
        length = data[0] * 256 + data[1];
        if(length > 0)
        {
            memset(data, 0, sizeof(data));
            result = GtToolkitExt::readN(_networkSocket, data, length, _networkTimeout);
            if(result != 0)
            {
                GtToolkitExt::logError(__FILE__, __LINE__, "[%d]接收文件下载数据错误", result);
                return result;
            }
        }
        else
        {
            continue;
        }
        //编码转换
        memset(u8Data, 0, sizeof(u8Data));
        if(GtToolkitExt::gbkToUtf8((char *)data, length, u8Data, sizeof(u8Data), &u8Length) != 0)
        {
            GtToolkitExt::logError(__FILE__, __LINE__, "[<--]数据编码转换错误");
            memcpy(u8Data, data, length);
            u8Length = length;
        }
        //校验交易码
        memset(tmpBuf, 0, sizeof(tmpBuf));
        result = GtToolkitExt::parseNChar((char *)data, tmpBuf, sizeof(tmpBuf), Gt::_delimiter1, 1);
        if(result != 0)
        {
            GtToolkitExt::logError(__FILE__, __LINE__, "[%d]交易码字段解析错误", result);
            return result;
        }
        receiveCode = atol(tmpBuf);
        if(999102 != receiveCode && 999104 != tradingCode)
        {
            GtToolkitExt::logInfo(__FILE__, __LINE__, "[<--]%s", u8Data);
        }
        //解析应答
        //校验流水号
        memset(tmpBuf, 0, sizeof(tmpBuf));
        result = GtToolkitExt::parseNChar((char *)data, tmpBuf, sizeof(tmpBuf), Gt::_delimiter1, 4);
        if(result !=0 )
        {
            GtToolkitExt::logError(__FILE__, __LINE__, "[%d]流水号字段解析错误", result);
            return result;
        }
        receiveSN = atol(tmpBuf);
        if(receiveSN != uniqueSN)
        {
            GtToolkitExt::logError(__FILE__, __LINE__, "[%d]流水号校验错误", GtError::ERROR_INVALID_VALUE);
            return GtError::ERROR_INVALID_VALUE;
        }
        //校验交易码
        memset(tmpBuf, 0, sizeof(tmpBuf));
        result = GtToolkitExt::parseNChar((char *)data, tmpBuf, sizeof(tmpBuf), Gt::_delimiter1, 1);
        if(result != 0)
        {
            GtToolkitExt::logError(__FILE__, __LINE__, "[%d]交易码字段解析错误", result);
            return result;
        }
        receiveCode = atol(tmpBuf);
        if(receiveCode != 999999)
        {
            if(receiveCode != tradingCode)
            {
                GtToolkitExt::logError(__FILE__, __LINE__, "[%d]交易码校验错误", GtError::ERROR_INVALID_VALUE);
                return GtError::ERROR_INVALID_VALUE;
            }
        }
        else
        {
            //校验交易码
            memset(tmpBuf, 0, sizeof(tmpBuf));
            result = GtToolkitExt::parseNChar((char *)data, tmpBuf, sizeof(tmpBuf), Gt::_delimiter1, 6);
            if(result !=0 )
            {
                GtToolkitExt::logError(__FILE__, __LINE__, "[%d]交易码字段解析错误", result);
                return result;
            }
            receiveCode = atol(tmpBuf);
            if(receiveCode != tradingCode)
            {
                GtToolkitExt::logError(__FILE__, __LINE__, "[%d]交易码校验错误", GtError::ERROR_INVALID_VALUE);
                return GtError::ERROR_INVALID_VALUE;
            }
            //校验错误码
            memset(tmpBuf, 0, sizeof(tmpBuf));
            result = GtToolkitExt::parseNChar((char *)data, tmpBuf, sizeof(tmpBuf), Gt::_delimiter1, 3);
            if(result != 0)
            {
                GtToolkitExt::logError(__FILE__, __LINE__, "[%d]错误码字段解析错误", result);
                return result;
            }
            _errorCode = atoi(tmpBuf);
            memset(_errorMsg, 0, sizeof(_errorMsg));
            result = GtToolkitExt::parseNChar((char *)data, _errorMsg, sizeof(_errorMsg), Gt::_delimiter1, 7);
            if(result != 0)
            {
                GtToolkitExt::logError(__FILE__, __LINE__, "[%d]错误描述字段解析错误", result);
                return result;
            }
            return _errorCode;
        }
        break;
    }
    result = GtToolkitExt::parseNCharIndex((char *)data, Gt::_delimiter1, 5);
    if(result < 0)
    {
        GtToolkitExt::logError(__FILE__, __LINE__, "[%d]数据解析错误", result);
        return result;
    }
    memcpy(outBuf, &data[result + 1], length - result - 1);
    *outLen = length - result - 1;
     outBuf[length - result - 1] = '\0';
    return 0;
}
