#ifdef SBKDLL


#include "DataProcess/tools.h"
#include "DataProcess/rollback.h"
#include <qwinwidget.h>

#include <QMessageBox>
#include <QDateTime>
#include <windows.h>
#include "control.h"
#include "global.h"
#include "QsLog.h"
#include "requestmodel.h"
#include "fmtool.h"
#include "rspfactory.h"
#include "fmp_settings.h"
#include "version.h"

#include <QDir>

EXTERN_C IMAGE_DOS_HEADER __ImageBase;

static void InitLogger()
{

    char path[MAX_PATH] = {0};
    ToolS::GetProcPath(path);

    FMPSettings setting;
    QString logPath = setting.GetValue(CONFIG_LOG_PATH, QString(path)+"/log").toString();
    QString logName = setting.GetValue(CONFIG_LOG_NAME, "sbuxpay.txt").toString();
    QsLogging::Level logLevel = (QsLogging::Level)setting.GetValue(CONFIG_LOG_LEVEL, 0).toInt();
    if(logLevel < QsLogging::TraceLevel || logLevel > QsLogging::OffLevel) {
        logLevel = QsLogging::TraceLevel;
    }
    int logSize = setting.GetValue(CONFIG_LOG_SIZE, 1).toInt();
    int logCount = setting.GetValue(CONFIG_LOG_COUNT, 20).toInt();

    QDir logDir(logPath);
    if(!logDir.exists()) {
        logDir.mkpath(logDir.absolutePath());
    }
    QString logFilePath = logDir.absolutePath()+'/'+logName;
    QsLogging::Logger& logger = QsLogging::Logger::instance();
    logger.setLoggingLevel(logLevel);

    /* 配置输出定向器 */
    QsLogging::DestinationPtr fileDestination(QsLogging::DestinationFactory::MakeFileDestination(
    logFilePath,
    QsLogging::EnableLogRotation, QsLogging::MaxSizeBytes(1024*1024*logSize),
                                  QsLogging::MaxOldLogCount(logCount)));
    logger.addDestination(fileDestination);

    QsLogging::DestinationPtr consleDest(QsLogging::DestinationFactory::MakeDebugOutputDestination());
    logger.addDestination(consleDest);
}

BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpvReserved*/ )
{
    static bool ownApplication = FALSE;

    if ( dwReason == DLL_PROCESS_ATTACH ) {
        char mod[MAX_PATH] = { 0 };
        GetModuleFileNameA((HMODULE)&__ImageBase, mod, MAX_PATH);
        char *ch = strrchr(mod,'\\');
        if (ch++) {
            *ch = '\0';
        }
        QString path = QString::fromLocal8Bit(mod);
        path = path.replace("\\", "/");
        QApplication::addLibraryPath(path);
        QByteArray val = qgetenv("PATH");
        val += ";";
        val += mod;
        qputenv("PATH", val);

        FMPSettings setting;
        QString configPath = setting.GetValue(CONFIG_ALL_PATH, path).toString();
        QApplication::addLibraryPath(configPath);

        qDebug() << "Library paths: " << QApplication::libraryPaths() << configPath;

        InitLogger();

        QLOG_INFO() << QString("Program run. Version: %1.%2.%3.%4").arg(VER_MAJOR).arg(VER_MINOR).arg(VER_REVISION).arg(VER_BUILD);

        ownApplication = QMfcApp::pluginInstance( hInstance );
    }
    if ( dwReason == DLL_PROCESS_DETACH && ownApplication )
    delete qApp;

    return TRUE;
}

extern "C" __declspec(dllexport) void Start(const char *indata, char *outdata)
{
    HWND parent = GetDesktopWindow();
    QWinWidget win( parent );

    Control control(&win);
    control.Start(indata, outdata);

    static RollBack rollback;
    if(!rollback.isRunning())
        rollback.start();
}


#else

#ifdef FM_TEST

#include "control.h"
#include "global.h"
#include "QsLog.h"
#include "requestmodel.h"
#include "fmtool.h"
#include "rspfactory.h"
#include <QDir>
#include <QApplication>
#include "DataProcess/rollback.h"
#include <QStringList>
#include "DataProcess/dataprocess.h"
#include "DataProcess/cretopt.h"


static RollBack rollback;

void TestSetString()
{
    AlipayResponse repon;

    FMTool::SetString(repon.ResponseMsg, 40, QString::fromLocal8Bit("sb"));
}

void TestSetPinter()
{
     AlipayResponse repon;

    QJsonObject obj, json;
    obj.insert("print", "dasdas");

    json.insert("ext", obj);

    RspFactory::SetPinter(repon, json);

    qDebug() << "lalal";

}

void TestGetResPonseJson()
{
     AlipayResponse repon;

    QJsonObject obj, json;
    obj.insert("print", "dasdas");

    json.insert("ext", obj);
    json.insert("fmId", "asdashdgajshdg11111111111111111");
    json.insert("statusCode", 100);
    json.insert("message", "asdasd");

    RspFactory::GetResPonseJson(pay, repon, json);

    qDebug() << "lalal";

    json.insert("statusCode", 204);
    json.insert("message", "asdasd");

    RspFactory::GetResPonseJson(refund, repon, json);

    qDebug() << "lalal";

}

void TestGetResPonseWithError()
{
    AlipayResponse repon;

    RspFactory::GetResPonseWithError(repon, "201", "asdasd");

    qDebug() << "lalal";

}

typedef int (* GetValue) (char *, char *);
typedef int (__stdcall * GetRSACret)(int ,const char *,const char *);

void TestDllWapper()
{
    QLibrary lib(qApp->applicationDirPath() + "/" + "FreemudWrapper.dll");

    if(lib.load())
    {
        GetValue getvalue = (GetValue)lib.resolve("_GetValue@8");
        GetRSACret getrsacret = (GetRSACret)lib.resolve("_GetRSACret@12");

        qDebug() << getvalue;
        qDebug() << getrsacret;

        int j = -1;

        char t1[25600] = {0};
        char t2[25600] = {0};

       // getrsacret();

        //int i = getrsacret(1 , "1314", "2678");


        getvalue(t1, t2);

        qDebug() << j;

        qDebug() << t1;
        qDebug() << t2;
    }
    else
        qDebug() << "load error";

}

void TestDllFmclient()
{
    QLibrary lib(qApp->applicationDirPath() + "/" + "test02.dll");

    qDebug() << qApp->applicationDirPath() + "/" + "test02.dll";

    if(lib.load())
    {
        GetValue getvalue = (GetValue)lib.resolve("GetValue");
        GetRSACret getrsacret = (GetRSACret)lib.resolve("_GetRSACret@12");

        qDebug() << getvalue;
        qDebug() << getrsacret;

        int j = -1;

       // getrsacret();

        getrsacret(1 , "1314", "2678");


        qDebug() << j;
    }

}

void TestDataProcess()
{
    QJsonObject json;
    QJsonObject obj;

    json.insert("awqwe", 2);
    json.insert("Sklhfwj", "hello");
    json.insert("oiueqw","");
    json.insert("sign","jeqweqwje287398217");

    obj.insert("ldd", "hahahah");

    json.insert("lcd", obj);

    qDebug() << json;

    QStringList list;

    DataProcess::GetJsonKeyArray(list, json);

    qDebug() << "not sort" << list;

    DataProcess::SortString(list);

    qDebug() << "sort" << list;

    QString value;

    DataProcess::GetValueFromJson(list, json, value);

    qDebug() << value;

}

void TestCret()
{
    QJsonObject json;
    QJsonObject obj;
    QString sign;

    json.insert("awqwe", 2);
    json.insert("Sklhfwj", "hello");
    json.insert("oiueqw","");
    json.insert("sign","jeqweqwje287398217");

    obj.insert("ldd", "hahahah");

    json.insert("lcd", obj);

    qDebug() << json;

    CretOperate::GetSign(json, sign);

    qDebug() << json;
}



int main(int argc, char *argv[])
{

    QApplication a(argc, argv);

    QString logDir = QString("%1/log").arg(QApplication::applicationDirPath());
    QDir().mkdir(logDir);
    QsLogging::Logger& logger = QsLogging::Logger::instance();
    logger.setLoggingLevel(QsLogging::TraceLevel);
    QString str = qApp->applicationDirPath() + "/log/mcduncompress.txt";

    /* 配置输出定向器 */
    QsLogging::DestinationPtr fileDestination(QsLogging::DestinationFactory::MakeFileDestination(
    str,
    QsLogging::EnableLogRotation, QsLogging::MaxSizeBytes(1024*1024),
                                  QsLogging::MaxOldLogCount(5)));
    logger.addDestination(fileDestination);

    QsLogging::DestinationPtr consleDest(QsLogging::DestinationFactory::MakeDebugOutputDestination());
    logger.addDestination(consleDest);

    //pass
    //TestSetString();
    //pass
    //TestGetResPonseWithError();
    //pass
    //TestSetPinter();
    //pass
    //TestGetResPonseJson();
    //error
    //TestDllWapper();
    //
    //TestDllFmclient();

    //pass
    TestDataProcess();

    TestCret();

    qDebug() << "1212367123";

    AlipayRequest req;

    FMTool::SetString(req.BusinessDay, 8 , QString("20170909"));
    FMTool::SetString(req.TransType, 2 , QString("30"));
    FMTool::SetString(req.PlatNo, 4, QString("1443"));
    FMTool::SetString(req.TransTime, 6, QString("130301"));
    FMTool::SetString(req.StoreNo, 20 , QString("17607"));
    FMTool::SetString(req.DeviceNo, 6 , QString("1"));
    FMTool::SetString(req.CashierNo, 6 , QString("0123"));
    FMTool::SetString(req.CashTraceNo, 6 , QString("16723"));
    FMTool::SetString(req.OriginTrace, 64 , QString(""));
    FMTool::SetString(req.Amount, 12, QString("1"));
    FMTool::SetString(req.Reserved1, 48 , QString("1367623098735894422"));
    req.item_line_qty[0] = '2';
    req.item_line_qty[1] = ' ';


    struct product{
        char productID[8]; //商品id
        char buyCount[4]; //购买数量
        char unitPrice[8]; //单件商品价格
        char isCombo[1]; //默认为0
        char isNonsale[1]; //(废弃)
        char productName[20]; //商品名字
    };

    for(int i = 0; i < 99; ++i)
    {

        struct product *pro = (struct product *)req.item_information[i];

        FMTool::SetString(pro->productID, 8,QString::number(i+1));
        FMTool::SetString(pro->buyCount, 4,QString::number(i+1));
        FMTool::SetString(pro->unitPrice, 8,QString::number(i+1));
        FMTool::SetString(pro->isCombo, 1,QString::number(i%2));
        FMTool::SetString(pro->isNonsale, 1,QString::number(i+1));
        FMTool::SetString(pro->productName, 20,QString::fromLocal8Bit("asdasdasd"));

    }



    char as[MAX_BUF_LEN] = {0};

    memcpy(as, &req, sizeof(struct AlipayRequest));

    Control control;

    rollback.start();

    //char as[] = "ak10dh171300000000000    *#dhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh";
    char b[MAX_BUF_LEN] = {0};

//    control.Start(as, b);

//    char spccIn[MAX_BUF_LEN] = "{\"fmId\":\"11971709011000000002\",\"reqType\":352,\"storeId\":\"1713\",\"stationId\":\"1\",\"partnerId\":1438,\"operatorId\":\"0123\",\"transId\":301439,\"transAmount\":1,\"partnerOrderId\":\"909911039990170830002\",\"businessDate\":\"20170508\",\"products\":[{\"pid\":\"123\",\"name\":\"中杯拿铁\",\"price\":321,\"salesType\":\"NORMAL\"}]}";
    char spccIn[MAX_BUF_LEN] = "{\"reqType\":352,\"storeId\":\"1713\",\"stationId\":\"1\",\"partnerId\":1438,\"operatorId\":\"0123\",\"transId\":301439,\"transAmount\":1,\"partnerOrderId\":\"201709280001\",\"businessDate\":\"20170830\"}";
//    char spccIn[MAX_BUF_LEN] = "{\"fmId\":\"64761709011000001002\",\"reqType\":453,\"storeId\":\"17607\",\"stationId\":\"1\",\"partnerId\":1443,\"operatorId\":\"0123\",\"transId\":301439,\"transAmount\":1,\"partnerOrderId\":\"1365670843098735011754\",\"businessDate\":\"20170830\"}";
    control.Start(spccIn, b);

    return a.exec();
}

#endif //! FM_TEST

#endif //! #ifdef SBKDLL
