#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 <QDir>

EXTERN_C IMAGE_DOS_HEADER __ImageBase;

static bool CopyApiDll(QString &errorString)
{

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

    QString localDllPath = QString::fromLocal8Bit("%1/StarbucksAPI.dll").arg(qApp->applicationDirPath());
    QFileInfo localFileInfo(localDllPath);

    FMPSettings setting;
    QString configDllPath = setting.GetValue(CONFIG_OLTP_PATH, "C:\\OLTP\\").toString();
    QFileInfo configFileInfo(configDllPath);

    if(!configFileInfo.isFile()) {
        configFileInfo = QFileInfo(configDllPath+"/StarbucksAPI.dll");
    }

    if(!configFileInfo.exists()) {
        errorString = "Config dll path: " + configDllPath + " does not exist.";
        QLOG_ERROR() << errorString;
        return false;
    }

    if(!localFileInfo.exists() || localFileInfo.lastModified() < configFileInfo.lastModified()) {
        QFile localDllFile(localFileInfo.absoluteFilePath());
        if(localDllFile.exists()) {
            localDllFile.remove();
        }
        QFile configDllFile(configFileInfo.absoluteFilePath());
        if(!configDllFile.copy(localDllPath)) {
            errorString = "Can't copy StarbucksAPI.dll: " + configDllFile.errorString();
            QLOG_ERROR() << errorString;
            return false;
        }
    }

    return true;
}


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);
        QDir::setCurrent(path);

        FMPSettings setting;
        QString configPath = setting.GetValue(CONFIG_ALL_PATH, "C:\\Freemud\\").toString();
        QApplication::addLibraryPath(configPath);

        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 );

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

    QString logDir = QString("%1/log").arg(QString(path));
    QDir().mkdir(logDir);
    QsLogging::Logger& logger = QsLogging::Logger::instance();
    logger.setLoggingLevel(QsLogging::TraceLevel);
    QString str = QString(path) + "\\log\\sbuxpay.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);

    QString errorString;
    if(!CopyApiDll(errorString)) {
//        errorString = QString::fromLocal8Bit("{\"statusCode\":23, \"message\":\"%1\"}").arg(errorString);
//        strcpy(outdata, errorString.toLocal8Bit());
//        return;
    }

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

    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\":\"37941708301000003002\",\"reqType\":451,\"storeId\":\"17607\",\"stationId\":\"1\",\"partnerId\":1443,\"operatorId\":\"0123\",\"transId\":301439,\"transAmount\":1,\"partnerOrderId\":\"909911039990170830002\",\"businessDate\":\"20170508\",\"products\":[{\"pid\":\"123\",\"name\":\"中杯拿铁\",\"price\":321,\"salesType\":\"NORMAL\"}]}";
    char spccIn[MAX_BUF_LEN] = "{\"reqType\":452,\"storeId\":\"17607\",\"stationId\":\"1\",\"partnerId\":1443,\"operatorId\":\"0123\",\"transId\":301439,\"transAmount\":1,\"partnerOrderId\":\"1365670843098735301654\",\"businessDate\":\"20170830\"}";
    control.Start(spccIn, b);

    return a.exec();
}

#endif //! FM_TEST

#endif //! #ifdef SBKDLL
