#include <QCoreApplication>
#include <QCommandLineParser>
#include <QCommandLineOption>

#include <windows.h>
#include <process.h>
#include <Tlhelp32.h>
#include <winbase.h>

#include <DLog>

#include "tool.h"
#include "servicemanager.h"

#define SERVICE_NAME  ("Deepin Legalization Agent")

void stopService()
{
    ServiceManager sc;
    sc.Open();
    sc.Stop(SERVICE_NAME);
}

void startService()
{
    ServiceManager sc;
    sc.Open();
    sc.Start(SERVICE_NAME);
}

void killProcessByName(const QString &filename)
{
    HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
    PROCESSENTRY32 pEntry;
    pEntry.dwSize = sizeof(pEntry);
    BOOL hRes = Process32First(hSnapShot, &pEntry);
    while (hRes) {
        if (filename == QString::fromWCharArray(pEntry.szExeFile)) {
            qDebug() <<  QString::fromWCharArray(pEntry.szExeFile);
            HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0,
                                          (DWORD) pEntry.th32ProcessID);
            if (hProcess != nullptr) {
                TerminateProcess(hProcess, 9);
                CloseHandle(hProcess);
            }
        }
        hRes = Process32Next(hSnapShot, &pEntry);
    }
    CloseHandle(hSnapShot);
}

void extractZip(const QString &zipPath, const QString &destDir)
{
    auto unzipPath = qApp->applicationDirPath() + "/" + "unzip.exe";
    QProcess unzipApp;
    unzipApp.setProgram(unzipPath);
    unzipApp.setArguments(QStringList() << "-o" << "-x" << zipPath << "-d" << destDir);
    unzipApp.start();
    unzipApp.waitForStarted(-1);
    unzipApp.waitForFinished(-1);
    qDebug() << unzipPath;
    qDebug() << unzipApp.arguments();
    while (unzipApp.canReadLine()) {
        qDebug() << QString::fromLocal8Bit(unzipApp.readLine());
    }
    qDebug() << QString::fromLocal8Bit(unzipApp.readAllStandardError());
    qDebug() << unzipApp.exitStatus() << unzipApp.exitCode();
}

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

    app.setOrganizationName("deepin");
    app.setApplicationName("deepin-legalization-updater");

    Dtk::Core::DLogManager::setlogFilePath(app.applicationDirPath() + "\\install.log");
    Dtk::Core::DLogManager::registerConsoleAppender();
    Dtk::Core::DLogManager::registerFileAppender();

    app.setApplicationVersion(Tool::getVersion());

    if (!Tool::setSingleInstance(app.applicationName())) {
        qWarning() << "anthorer instance is running!";
        return 0;
    }

    qDebug() << "start update";

    QCommandLineParser parser;
    parser.addPositionalArgument("updateArcive", "update zip package");
    parser.addPositionalArgument("installDir", "install directory");
    parser.process(app);

    if (parser.positionalArguments().count() != 2) {
        qCritical() << "argument count error";
        parser.showHelp();
    }

    stopService();
    QThread::sleep(2);
    for (int i = 0; i < 3; ++i) {
        killProcessByName("deepin-legalization-agent.exe");
        QThread::sleep(1);
    }

    for (int i = 0; i < 3; ++i) {
        killProcessByName("deepin-legalization-checker.exe");
        QThread::sleep(1);
    }
    killProcessByName("deepin-legalization-agent.exe");
    killProcessByName("deepin-legalization-checker.exe");

    auto updateArcivePath = parser.positionalArguments().value(0);
    auto installDir = parser.positionalArguments().value(1);

    extractZip(updateArcivePath, installDir);
    qDebug() << "extractZip" << updateArcivePath << "to" << installDir;
    startService();
    qDebug() << "startService";
    qDebug() << "finish update";
    QFile::copy(Dtk::Core::DLogManager::getlogFilePath(), installDir + "\\update.log");
    return 0;
}
