#include "mainwindow.h"
#include <QApplication>
#include <QSplashScreen>
//#include <JQHttpServer.h>
#include "ccrashstack.h"
//#include "DbgHelp.h"

#ifdef Q_OS_WIN
long __stdcall   callback(_EXCEPTION_POINTERS*   excp)
{
    CCrashStack crashStack(excp);
    QString sCrashInfo = crashStack.GetExceptionInfo();

//    TCHAR my_documents[MAX_PATH];
//    SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, my_documents);
//    QString file_path = QString::fromWCharArray(my_documents);
    QDir dir;
    QString file_path = dir.currentPath();
    QDir *folder_path = new QDir;
    bool exist = folder_path->exists(file_path.append("\\MyApp"));
    if(!exist)
    {
        folder_path->mkdir(file_path);
    }
    delete folder_path;
    folder_path = nullptr;

    QString sFileName = "d:\\mycrash.log";

    QFile file(sFileName);
    if (file.open(QIODevice::WriteOnly|QIODevice::Truncate))
    {
        file.write(sCrashInfo.toUtf8());
        file.close();
    }
            QMessageBox::critical(NULL,"程式崩溃","<FONT size=4><div><b>程序崩溃，请将d盘根目录下的mycrash.log文件发送到fyx@xixunled.com邮箱</b><br/></div>"+
                QString("研发人员会尽快处理修改程序bug，并给出解决方案"),
                QMessageBox::Ok);
    return   EXCEPTION_EXECUTE_HANDLER;
}
#endif

//static LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException)
//{
//    //And output crash information
//    EXCEPTION_RECORD *record = pException->ExceptionRecord;
//    QString errCode(QString::number(record->ExceptionCode, 16));
//    QString errAddr(QString::number((uint)record->ExceptionAddress, 16));
//    QString errFlag(QString::number(record->ExceptionFlags, 16));
//    QString errPara(QString::number(record->NumberParameters, 16));
//    qDebug()<<"errCode: "<<errCode;
//    qDebug()<<"errAddr: "<<errAddr;
//    qDebug()<<"errFlag: "<<errFlag;
//    qDebug()<<"errPara: "<<errPara;
//    //Create the dump file
//    //HANDLE hDumpFile = CreateFile((LPCWSTR)QString("../bin_vs/crash.dmp").utf16(),
//    HANDLE hDumpFile = CreateFile((LPCWSTR)QString("crash.dmp").utf16(),
//             GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
//    if(hDumpFile != INVALID_HANDLE_VALUE) {
//        MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
//        dumpInfo.ExceptionPointers = pException;
//        dumpInfo.ThreadId = GetCurrentThreadId();
//        dumpInfo.ClientPointers = TRUE;
//        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
//        CloseHandle(hDumpFile);
//    }
//    //这里弹出一个错误对话框并退出程序
//        QMessageBox::critical(NULL,"程式崩溃","<FONT size=4><div><b>对于发生的错误，表示诚挚的歉意</b><br/></div>"+
//            QString("<div>错误代码：%1</div><div>错误地址：%2</div></FONT>").arg(errCode).arg(errAddr),
//            QMessageBox::Ok);
//    return EXCEPTION_EXECUTE_HANDLER;
//}
//主程序入口
int main(int argc, char *argv[])
{
     SetUnhandledExceptionFilter(callback);
//步骤3:
//通过qt命令行进入 执行命令：
//objdump -S xxx.exe >aaa.asm
//命令执行完成后，根据步骤2中获得的crash堆栈信息在aaa.asm中查找响应地址，即可得到崩溃具体位置。


//      SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);
//      在项目的proproject文件里增加：QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO /DEBUG
//      这句话的目的是Release版也将生成“.pdb”后缀的调试信息文件。在使用WinDbg导入Dump前。指定好源代码与pdb文件的位置。就可以在错误报告内看到罪魁祸首是哪一行代码。

    QApplication a(argc, argv);
    QSplashScreen *splash = new QSplashScreen;
    splash->setPixmap(QPixmap(":/res/splash.png"));
    splash->show();
    //Qt::Alignment topRight = Qt::AlignRight | Qt::AlignTop;
    splash->showMessage(QObject::tr("Setting up the LedOK Express...") , Qt::AlignRight | Qt::AlignTop , Qt::white);
 /*   JQHttpServer::TcpServerManage tcpServerManage( 2 ); // 设置最大处理线程数，默认2个
    tcpServerManage.setHttpAcceptedCallback( []( const QPointer< JQHttpServer::Session > &session )
    {
        // 回调发生在新的线程内，不是主线程，请注意线程安全
        // 若阻塞了此回调，那么新的连接将不会得到处理（默认情况下有2个线程可以阻塞2次，第3个连接将不会被处理）

 //       session->replyText( QString( "url:%1\nbody:%2" ).arg( session->requestUrl(), QString( session->requestBody() ) ) );
//        session->replyRedirects( QUrl( "http://www.baidu.com" ) );
//        session->replyJsonObject( { { { "message", "ok" } } } );
        QString strRequestUrl=session.data()->requestUrl();
        if(strRequestUrl.contains("/download?id="))
        {
            QString strId=strRequestUrl.right(strRequestUrl.length()-13);

            session->replyFile( "C:/Users/64549/Documents/LedOK Express/NPrograms/新建20200330111731834_tmp/"+strId );
        }
            //session->replyJsonArray( { "a", "b", "c" } );
//        session->replyFile( "G://11.o" );
//        session->replyImage( QImage( "/Users/jason/Desktop/Test.png" ) );
//        session->replyBytes(QByteArray(4,'\x24')); // $$$$

        // 注1：因为一个session对应一个单一的HTTP请求，所以session只能reply一次
        // 注2：在reply后，session的生命周期不可控，所以reply后不要再调用session的接口了
    } );
    qDebug() << "listen:" << tcpServerManage.listen( QHostAddress::Any, 23412 );

    splash->showMessage(QObject::tr("httpserver listen...") , Qt::AlignRight | Qt::AlignTop , Qt::white);
    */
    MainWindow w;
    //splash->showMessage(QObject::tr("Loading modules..."),Qt::AlignRight | Qt::AlignTop ,Qt::white);
    //loadModules();
    //splash->showMessage(QObject::tr("Establishing connections..."),Qt::AlignRight | Qt::AlignTop ,Qt::white);
    //establishConnections();
    splash->showMessage(QObject::tr("Setting up the LedOK Express OK!") , Qt::AlignRight | Qt::AlignTop , Qt::white);
    w.show();

    splash->finish(&w);
    delete splash;
    return a.exec();
}
