#include "updater/Updater.h"

#include "misc/Platform.h"
#include "misc/DataBuffer.h"

#include "network/HttpLib.h"

#ifdef _WIN32
#include <windows.h>
#include <cstdio>
#endif

namespace td {
namespace utils {

bool Updater::checkUpdate() {
    httplib::Client client("thesims.freeboxos.fr", 30000);

    if (auto res = client.Get("/Tower%20Defense/version")) {

        std::string currentVersion = getCurrentVersion();
        m_LastVersion = res.value().body;

        // we only look at the first line
        m_LastVersion = m_LastVersion.substr(0, m_LastVersion.find('\n'));

        std::cout << "Current version : [" << getCurrentVersion() << "]\n";
        std::cout << "Last version : [" << m_LastVersion << "]\n";

        if (currentVersion != m_LastVersion) {
            return true;
        }
        return false;
    } else {
        std::cerr << "Error : " << res.error() << std::endl;
        return false;
    }

    return false;
}

bool Updater::canUpdate() {
    return !getDownloadFileURL().empty();
}

std::string Updater::getDownloadFileURL() {
    Os systemOs = getSystemOs();
    Architecture systemArch = getSystemArchitecture();

    switch (systemOs) {

    case Os::Windows: {

        switch (systemArch) {
        case Architecture::x86_64:
            return "/Tower%20Defense/Tower%20Defense%20Windows%20(x86_64).exe";
        case Architecture::x86:
            return "/Tower%20Defense/Tower%20Defense%20Windows%20(x86).exe";
        default:
            return "";
        }

    }

    default: // not supported on Android and Linux (package managers are better)
        return "";
    }
}

std::string Updater::getLocalFilePath() {
#ifdef _WIN32
    char filePathBuffer[1024];
    GetModuleFileName(nullptr, filePathBuffer, sizeof(filePathBuffer));

    std::string filePath = filePathBuffer;
    return filePath;
#endif
    return "";
}

void Updater::downloadUpdate() {
    if (m_DownloadComplete) return;

    m_CancelDownload = false;

    std::string newFileUrl = getDownloadFileURL();

    httplib::Client client("thesims.freeboxos.fr", 30000);

    httplib::ContentReceiver reciever = [&](const char* data, size_t data_length) {
        std::string fileData(data, data_length);
        m_FileBuffer << fileData;
        return true;
    };

    httplib::Progress progress = [&](uint64_t len, uint64_t total) {
        m_Progress = (float)len * 100.0f / total;
        return !m_CancelDownload;
    };

    auto res = client.Get(newFileUrl.c_str(), reciever, progress);

    if (!m_CancelDownload) {
        m_DownloadComplete = true;
    }
}

void Updater::removeOldFile() {
    std::remove(std::string(getLocalFilePath() + "_old").c_str());
}

bool Updater::writeFile() {
    if (m_FileWrited || !m_DownloadComplete) return false;

    if (!m_FileBuffer.WriteFile(getLocalFilePath() + "_recent"))
        return false;

#ifdef _WIN32
    std::rename(getLocalFilePath().c_str(), std::string(getLocalFilePath() + "_old").c_str());
    std::rename(std::string(getLocalFilePath() + "_recent").c_str(), getLocalFilePath().c_str());
#endif

    m_FileWrited = true;
    m_DownloadComplete = false;

    clearCache();

    return true;
}

} // namespace utils
} // namespace td
