#include <QCoreApplication>
#include <QApplication>
#include <QDebug>
#include <QTimer>
#include <QFileInfo>

#include "message_handler.h"
#include "plugins/interfaces.h"

#include "DCPlugin/include/hwapi.h"

#include <unistd.h>
#include <thread>
#include <memory>

static void updateBinary(std::unique_ptr<hwinf> hw,     // update d2dc*.bin
                         char const *fileToSendToDC,
                         char const *baudrate,
                         char const *serialInterface) {
    for (int i=0; i < 1;++i) {
        hw->dc_updateDC(fileToSendToDC, baudrate, serialInterface);
        std::this_thread::sleep_for(std::chrono::milliseconds(3000));
    }
    QCoreApplication::quit();
}

static void updatePrinterConf(std::unique_ptr<hwinf> hw, // update printer-file
                              char const *fileToSendToDC,
                              char const *baudrate,
                              char const *serialInterface) {
    for (int i=0; i < 1;++i) {
        hw->dc_updateDC(fileToSendToDC, baudrate, serialInterface);
        std::this_thread::sleep_for(std::chrono::milliseconds(3000));
    }
    QCoreApplication::quit();
}

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

    if (!messageHandlerInstalled()) { // change internal qt-QDebug-handling
        atbInstallMessageHandler(atbDebugOutput);
        setDebugLevel(QtMsgType::QtDebugMsg);
        //setDebugLevel(QtMsgType::QtDebugMsg);
    }

    if (argc > 2) {
        qCritical() << "Usage: " << argv[0] << "<file to send to dc>";
        return -1;
    }

    std::unique_ptr<hwinf> hw(new hwapi());
    QFileInfo fileInfo(argv[1]);
    QString fname(fileInfo.fileName());
    int ret = 0;

    if (fname.startsWith("dc") && fname.endsWith(".bin")) {
#ifdef PTU5
        std::thread t(updateBinary, std::move(hw),
                      fname.toStdString().c_str(), "115200", "ttymxc2");
#else
        std::thread t(updateBinary, std::move(hw),
                      fname.toStdString().c_str(), "115200", "ttyUSB0");
#endif
        ret = a.exec();
        t.join();
    } else
    if (fname.startsWith("DC") && fname.endsWith(".json")) {
#ifdef PTU5
        std::thread t(updatePrinterConf, std::move(hw),
                      fname.toStdString().c_str(), "115200", "ttymxc2");
#else
        std::thread t(updatePrinterConf, std::move(hw),
                      fname.toStdString().c_str(), "115200", "ttyUSB0");
#endif
        ret = a.exec();
        t.join();
    }

    return ret;
}