/**
 * linglong仓库
 * 玲珑仓库接口
 *
 * The version of the OpenAPI document: 1.0.0
 * Contact: wurongjie@deepin.org
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

#include "ClientApi.h"
#include "ServerConfiguration.h"
#include <QJsonArray>
#include <QJsonDocument>

namespace linglong {
namespace api {
namespace client {

ClientApi::ClientApi(const int timeOut)
    : _timeOut(timeOut),
      _manager(nullptr),
      _isResponseCompressionEnabled(false),
      _isRequestCompressionEnabled(false) {
    initializeServerConfigs();
}

ClientApi::~ClientApi() {
}

void ClientApi::initializeServerConfigs() {
    //Default server
    QList<ServerConfiguration> defaultConf = QList<ServerConfiguration>();
    //varying endpoint server
    defaultConf.append(ServerConfiguration(
    QUrl("/"),
    "No description provided",
    QMap<QString, ServerVariable>()));
    _serverConfigs.insert("fuzzySearchApp", defaultConf);
    _serverIndices.insert("fuzzySearchApp", 0);
    _serverConfigs.insert("getRepo", defaultConf);
    _serverIndices.insert("getRepo", 0);
    _serverConfigs.insert("newUploadTaskID", defaultConf);
    _serverIndices.insert("newUploadTaskID", 0);
    _serverConfigs.insert("signIn", defaultConf);
    _serverIndices.insert("signIn", 0);
    _serverConfigs.insert("uploadTaskFile", defaultConf);
    _serverIndices.insert("uploadTaskFile", 0);
    _serverConfigs.insert("uploadTaskInfo", defaultConf);
    _serverIndices.insert("uploadTaskInfo", 0);
    _serverConfigs.insert("uploadTaskLayerFile", defaultConf);
    _serverIndices.insert("uploadTaskLayerFile", 0);
}

/**
* returns 0 on success and -1, -2 or -3 on failure.
* -1 when the variable does not exist and -2 if the value is not defined in the enum and -3 if the operation or server index is not found
*/
int ClientApi::setDefaultServerValue(int serverIndex, const QString &operation, const QString &variable, const QString &value) {
    auto it = _serverConfigs.find(operation);
    if (it != _serverConfigs.end() && serverIndex < it.value().size()) {
      return _serverConfigs[operation][serverIndex].setDefaultValue(variable,value);
    }
    return -3;
}
void ClientApi::setServerIndex(const QString &operation, int serverIndex) {
    if (_serverIndices.contains(operation) && serverIndex < _serverConfigs.find(operation).value().size()) {
        _serverIndices[operation] = serverIndex;
    }
}

void ClientApi::setApiKey(const QString &apiKeyName, const QString &apiKey) {
    _apiKeys.insert(apiKeyName, apiKey);
}

void ClientApi::setBearerToken(const QString &token) {
    _bearerToken = token;
}

void ClientApi::setUsername(const QString &username) {
    _username = username;
}

void ClientApi::setPassword(const QString &password) {
    _password = password;
}


void ClientApi::setTimeOut(const int timeOut) {
    _timeOut = timeOut;
}

void ClientApi::setWorkingDirectory(const QString &path) {
    _workingDirectory = path;
}

void ClientApi::setNetworkAccessManager(QNetworkAccessManager* manager) {
    _manager = manager;
}

/**
    * Appends a new ServerConfiguration to the config map for a specific operation.
    * @param operation The id to the target operation.
    * @param url A string that contains the URL of the server
    * @param description A String that describes the server
    * @param variables A map between a variable name and its value. The value is used for substitution in the server's URL template.
    * returns the index of the new server config on success and -1 if the operation is not found
    */
int ClientApi::addServerConfiguration(const QString &operation, const QUrl &url, const QString &description, const QMap<QString, ServerVariable> &variables) {
    if (_serverConfigs.contains(operation)) {
        _serverConfigs[operation].append(ServerConfiguration(
                    url,
                    description,
                    variables));
        return _serverConfigs[operation].size()-1;
    } else {
        return -1;
    }
}

/**
    * Appends a new ServerConfiguration to the config map for a all operations and sets the index to that server.
    * @param url A string that contains the URL of the server
    * @param description A String that describes the server
    * @param variables A map between a variable name and its value. The value is used for substitution in the server's URL template.
    */
void ClientApi::setNewServerForAllOperations(const QUrl &url, const QString &description, const QMap<QString, ServerVariable> &variables) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
    for (auto keyIt = _serverIndices.keyBegin(); keyIt != _serverIndices.keyEnd(); keyIt++) {
        setServerIndex(*keyIt, addServerConfiguration(*keyIt, url, description, variables));
    }
#else
    for (auto &e : _serverIndices.keys()) {
        setServerIndex(e, addServerConfiguration(e, url, description, variables));
    }
#endif
}

/**
    * Appends a new ServerConfiguration to the config map for an operations and sets the index to that server.
    * @param URL A string that contains the URL of the server
    * @param description A String that describes the server
    * @param variables A map between a variable name and its value. The value is used for substitution in the server's URL template.
    */
void ClientApi::setNewServer(const QString &operation, const QUrl &url, const QString &description, const QMap<QString, ServerVariable> &variables) {
    setServerIndex(operation, addServerConfiguration(operation, url, description, variables));
}

void ClientApi::addHeaders(const QString &key, const QString &value) {
    _defaultHeaders.insert(key, value);
}

void ClientApi::enableRequestCompression() {
    _isRequestCompressionEnabled = true;
}

void ClientApi::enableResponseCompression() {
    _isResponseCompressionEnabled = true;
}

void ClientApi::abortRequests() {
    Q_EMIT abortRequestsSignal();
}

QString ClientApi::getParamStylePrefix(const QString &style) {
    if (style == "matrix") {
        return ";";
    } else if (style == "label") {
        return ".";
    } else if (style == "form") {
        return "&";
    } else if (style == "simple") {
        return "";
    } else if (style == "spaceDelimited") {
        return "&";
    } else if (style == "pipeDelimited") {
        return "&";
    } else {
        return "none";
    }
}

QString ClientApi::getParamStyleSuffix(const QString &style) {
    if (style == "matrix") {
        return "=";
    } else if (style == "label") {
        return "";
    } else if (style == "form") {
        return "=";
    } else if (style == "simple") {
        return "";
    } else if (style == "spaceDelimited") {
        return "=";
    } else if (style == "pipeDelimited") {
        return "=";
    } else {
        return "none";
    }
}

QString ClientApi::getParamStyleDelimiter(const QString &style, const QString &name, bool isExplode) {

    if (style == "matrix") {
        return (isExplode) ? ";" + name + "=" : ",";

    } else if (style == "label") {
        return (isExplode) ? "." : ",";

    } else if (style == "form") {
        return (isExplode) ? "&" + name + "=" : ",";

    } else if (style == "simple") {
        return ",";
    } else if (style == "spaceDelimited") {
        return (isExplode) ? "&" + name + "=" : " ";

    } else if (style == "pipeDelimited") {
        return (isExplode) ? "&" + name + "=" : "|";

    } else if (style == "deepObject") {
        return (isExplode) ? "&" : "none";

    } else {
        return "none";
    }
}

void ClientApi::fuzzySearchApp(const Request_FuzzySearchReq &data) {
    QString fullPath = QString(_serverConfigs["fuzzySearchApp"][_serverIndices.value("fuzzySearchApp")].URL()+"/api/v0/apps/fuzzysearchapp");
    
    HttpRequestWorker *worker = new HttpRequestWorker(this, _manager);
    worker->setTimeOut(_timeOut);
    worker->setWorkingDirectory(_workingDirectory);
    HttpRequestInput input(fullPath, "POST");

    {

        
        QByteArray output = data.asJson().toUtf8();
        input.request_body.append(output);
    }
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
    for (auto keyValueIt = _defaultHeaders.keyValueBegin(); keyValueIt != _defaultHeaders.keyValueEnd(); keyValueIt++) {
        input.headers.insert(keyValueIt->first, keyValueIt->second);
    }
#else
    for (auto key : _defaultHeaders.keys()) {
        input.headers.insert(key, _defaultHeaders[key]);
    }
#endif

    connect(worker, &HttpRequestWorker::on_execution_finished, this, &ClientApi::fuzzySearchAppCallback);
    connect(this, &ClientApi::abortRequestsSignal, worker, &QObject::deleteLater);
    connect(worker, &QObject::destroyed, this, [this]() {
        if (findChildren<HttpRequestWorker*>().count() == 0) {
            Q_EMIT allPendingRequestsCompleted();
        }
    });

    worker->execute(&input);
}

void ClientApi::fuzzySearchAppCallback(HttpRequestWorker *worker) {
    QString error_str = worker->error_str;
    QNetworkReply::NetworkError error_type = worker->error_type;

    if (worker->error_type != QNetworkReply::NoError) {
        error_str = QString("%1, %2").arg(worker->error_str, QString(worker->response));
    }
    FuzzySearchApp_200_response output(QString(worker->response));
    worker->deleteLater();

    if (worker->error_type == QNetworkReply::NoError) {
        Q_EMIT fuzzySearchAppSignal(output);
        Q_EMIT fuzzySearchAppSignalFull(worker, output);
    } else {
        Q_EMIT fuzzySearchAppSignalE(output, error_type, error_str);
        Q_EMIT fuzzySearchAppSignalEFull(worker, error_type, error_str);
    }
}

void ClientApi::getRepo(const QString &repo) {
    QString fullPath = QString(_serverConfigs["getRepo"][_serverIndices.value("getRepo")].URL()+"/api/v1/repos/{repo}");
    
    
    {
        QString repoPathParam("{");
        repoPathParam.append("repo").append("}");
        QString pathPrefix, pathSuffix, pathDelimiter;
        QString pathStyle = "";
        if (pathStyle == "")
            pathStyle = "simple";
        pathPrefix = getParamStylePrefix(pathStyle);
        pathSuffix = getParamStyleSuffix(pathStyle);
        pathDelimiter = getParamStyleDelimiter(pathStyle, "repo", false);
        QString paramString = (pathStyle == "matrix") ? pathPrefix+"repo"+pathSuffix : pathPrefix;
        fullPath.replace(repoPathParam, paramString+QUrl::toPercentEncoding(::linglong::api::client::toStringValue(repo)));
    }
    HttpRequestWorker *worker = new HttpRequestWorker(this, _manager);
    worker->setTimeOut(_timeOut);
    worker->setWorkingDirectory(_workingDirectory);
    HttpRequestInput input(fullPath, "GET");


#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
    for (auto keyValueIt = _defaultHeaders.keyValueBegin(); keyValueIt != _defaultHeaders.keyValueEnd(); keyValueIt++) {
        input.headers.insert(keyValueIt->first, keyValueIt->second);
    }
#else
    for (auto key : _defaultHeaders.keys()) {
        input.headers.insert(key, _defaultHeaders[key]);
    }
#endif

    connect(worker, &HttpRequestWorker::on_execution_finished, this, &ClientApi::getRepoCallback);
    connect(this, &ClientApi::abortRequestsSignal, worker, &QObject::deleteLater);
    connect(worker, &QObject::destroyed, this, [this]() {
        if (findChildren<HttpRequestWorker*>().count() == 0) {
            Q_EMIT allPendingRequestsCompleted();
        }
    });

    worker->execute(&input);
}

void ClientApi::getRepoCallback(HttpRequestWorker *worker) {
    QString error_str = worker->error_str;
    QNetworkReply::NetworkError error_type = worker->error_type;

    if (worker->error_type != QNetworkReply::NoError) {
        error_str = QString("%1, %2").arg(worker->error_str, QString(worker->response));
    }
    GetRepo_200_response output(QString(worker->response));
    worker->deleteLater();

    if (worker->error_type == QNetworkReply::NoError) {
        Q_EMIT getRepoSignal(output);
        Q_EMIT getRepoSignalFull(worker, output);
    } else {
        Q_EMIT getRepoSignalE(output, error_type, error_str);
        Q_EMIT getRepoSignalEFull(worker, error_type, error_str);
    }
}

void ClientApi::newUploadTaskID(const QString &x_token, const Schema_NewUploadTaskReq &req) {
    QString fullPath = QString(_serverConfigs["newUploadTaskID"][_serverIndices.value("newUploadTaskID")].URL()+"/api/v1/upload-tasks");
    
    HttpRequestWorker *worker = new HttpRequestWorker(this, _manager);
    worker->setTimeOut(_timeOut);
    worker->setWorkingDirectory(_workingDirectory);
    HttpRequestInput input(fullPath, "POST");

    {

        
        QByteArray output = req.asJson().toUtf8();
        input.request_body.append(output);
    }
    
    {
        if (!::linglong::api::client::toStringValue(x_token).isEmpty()) {
            input.headers.insert("X-Token", ::linglong::api::client::toStringValue(x_token));
        }
        }
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
    for (auto keyValueIt = _defaultHeaders.keyValueBegin(); keyValueIt != _defaultHeaders.keyValueEnd(); keyValueIt++) {
        input.headers.insert(keyValueIt->first, keyValueIt->second);
    }
#else
    for (auto key : _defaultHeaders.keys()) {
        input.headers.insert(key, _defaultHeaders[key]);
    }
#endif

    connect(worker, &HttpRequestWorker::on_execution_finished, this, &ClientApi::newUploadTaskIDCallback);
    connect(this, &ClientApi::abortRequestsSignal, worker, &QObject::deleteLater);
    connect(worker, &QObject::destroyed, this, [this]() {
        if (findChildren<HttpRequestWorker*>().count() == 0) {
            Q_EMIT allPendingRequestsCompleted();
        }
    });

    worker->execute(&input);
}

void ClientApi::newUploadTaskIDCallback(HttpRequestWorker *worker) {
    QString error_str = worker->error_str;
    QNetworkReply::NetworkError error_type = worker->error_type;

    if (worker->error_type != QNetworkReply::NoError) {
        error_str = QString("%1, %2").arg(worker->error_str, QString(worker->response));
    }
    NewUploadTaskID_200_response output(QString(worker->response));
    worker->deleteLater();

    if (worker->error_type == QNetworkReply::NoError) {
        Q_EMIT newUploadTaskIDSignal(output);
        Q_EMIT newUploadTaskIDSignalFull(worker, output);
    } else {
        Q_EMIT newUploadTaskIDSignalE(output, error_type, error_str);
        Q_EMIT newUploadTaskIDSignalEFull(worker, error_type, error_str);
    }
}

void ClientApi::signIn(const Request_Auth &data) {
    QString fullPath = QString(_serverConfigs["signIn"][_serverIndices.value("signIn")].URL()+"/api/v1/sign-in");
    
    HttpRequestWorker *worker = new HttpRequestWorker(this, _manager);
    worker->setTimeOut(_timeOut);
    worker->setWorkingDirectory(_workingDirectory);
    HttpRequestInput input(fullPath, "POST");

    {

        
        QByteArray output = data.asJson().toUtf8();
        input.request_body.append(output);
    }
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
    for (auto keyValueIt = _defaultHeaders.keyValueBegin(); keyValueIt != _defaultHeaders.keyValueEnd(); keyValueIt++) {
        input.headers.insert(keyValueIt->first, keyValueIt->second);
    }
#else
    for (auto key : _defaultHeaders.keys()) {
        input.headers.insert(key, _defaultHeaders[key]);
    }
#endif

    connect(worker, &HttpRequestWorker::on_execution_finished, this, &ClientApi::signInCallback);
    connect(this, &ClientApi::abortRequestsSignal, worker, &QObject::deleteLater);
    connect(worker, &QObject::destroyed, this, [this]() {
        if (findChildren<HttpRequestWorker*>().count() == 0) {
            Q_EMIT allPendingRequestsCompleted();
        }
    });

    worker->execute(&input);
}

void ClientApi::signInCallback(HttpRequestWorker *worker) {
    QString error_str = worker->error_str;
    QNetworkReply::NetworkError error_type = worker->error_type;

    if (worker->error_type != QNetworkReply::NoError) {
        error_str = QString("%1, %2").arg(worker->error_str, QString(worker->response));
    }
    SignIn_200_response output(QString(worker->response));
    worker->deleteLater();

    if (worker->error_type == QNetworkReply::NoError) {
        Q_EMIT signInSignal(output);
        Q_EMIT signInSignalFull(worker, output);
    } else {
        Q_EMIT signInSignalE(output, error_type, error_str);
        Q_EMIT signInSignalEFull(worker, error_type, error_str);
    }
}

void ClientApi::uploadTaskFile(const QString &x_token, const QString &task_id, const HttpFileElement &file) {
    QString fullPath = QString(_serverConfigs["uploadTaskFile"][_serverIndices.value("uploadTaskFile")].URL()+"/api/v1/upload-tasks/{task_id}/tar");
    
    
    {
        QString task_idPathParam("{");
        task_idPathParam.append("task_id").append("}");
        QString pathPrefix, pathSuffix, pathDelimiter;
        QString pathStyle = "";
        if (pathStyle == "")
            pathStyle = "simple";
        pathPrefix = getParamStylePrefix(pathStyle);
        pathSuffix = getParamStyleSuffix(pathStyle);
        pathDelimiter = getParamStyleDelimiter(pathStyle, "task_id", false);
        QString paramString = (pathStyle == "matrix") ? pathPrefix+"task_id"+pathSuffix : pathPrefix;
        fullPath.replace(task_idPathParam, paramString+QUrl::toPercentEncoding(::linglong::api::client::toStringValue(task_id)));
    }
    HttpRequestWorker *worker = new HttpRequestWorker(this, _manager);
    worker->setTimeOut(_timeOut);
    worker->setWorkingDirectory(_workingDirectory);
    HttpRequestInput input(fullPath, "PUT");

    
    {
        input.add_file("file", file.local_filename, file.request_filename, file.mime_type);
    }

    
    {
        if (!::linglong::api::client::toStringValue(x_token).isEmpty()) {
            input.headers.insert("X-Token", ::linglong::api::client::toStringValue(x_token));
        }
        }
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
    for (auto keyValueIt = _defaultHeaders.keyValueBegin(); keyValueIt != _defaultHeaders.keyValueEnd(); keyValueIt++) {
        input.headers.insert(keyValueIt->first, keyValueIt->second);
    }
#else
    for (auto key : _defaultHeaders.keys()) {
        input.headers.insert(key, _defaultHeaders[key]);
    }
#endif

    connect(worker, &HttpRequestWorker::on_execution_finished, this, &ClientApi::uploadTaskFileCallback);
    connect(this, &ClientApi::abortRequestsSignal, worker, &QObject::deleteLater);
    connect(worker, &QObject::destroyed, this, [this]() {
        if (findChildren<HttpRequestWorker*>().count() == 0) {
            Q_EMIT allPendingRequestsCompleted();
        }
    });

    worker->execute(&input);
}

void ClientApi::uploadTaskFileCallback(HttpRequestWorker *worker) {
    QString error_str = worker->error_str;
    QNetworkReply::NetworkError error_type = worker->error_type;

    if (worker->error_type != QNetworkReply::NoError) {
        error_str = QString("%1, %2").arg(worker->error_str, QString(worker->response));
    }
    Api_UploadTaskFileResp output(QString(worker->response));
    worker->deleteLater();

    if (worker->error_type == QNetworkReply::NoError) {
        Q_EMIT uploadTaskFileSignal(output);
        Q_EMIT uploadTaskFileSignalFull(worker, output);
    } else {
        Q_EMIT uploadTaskFileSignalE(output, error_type, error_str);
        Q_EMIT uploadTaskFileSignalEFull(worker, error_type, error_str);
    }
}

void ClientApi::uploadTaskInfo(const QString &x_token, const QString &task_id) {
    QString fullPath = QString(_serverConfigs["uploadTaskInfo"][_serverIndices.value("uploadTaskInfo")].URL()+"/api/v1/upload-tasks/{task_id}/status");
    
    
    {
        QString task_idPathParam("{");
        task_idPathParam.append("task_id").append("}");
        QString pathPrefix, pathSuffix, pathDelimiter;
        QString pathStyle = "";
        if (pathStyle == "")
            pathStyle = "simple";
        pathPrefix = getParamStylePrefix(pathStyle);
        pathSuffix = getParamStyleSuffix(pathStyle);
        pathDelimiter = getParamStyleDelimiter(pathStyle, "task_id", false);
        QString paramString = (pathStyle == "matrix") ? pathPrefix+"task_id"+pathSuffix : pathPrefix;
        fullPath.replace(task_idPathParam, paramString+QUrl::toPercentEncoding(::linglong::api::client::toStringValue(task_id)));
    }
    HttpRequestWorker *worker = new HttpRequestWorker(this, _manager);
    worker->setTimeOut(_timeOut);
    worker->setWorkingDirectory(_workingDirectory);
    HttpRequestInput input(fullPath, "GET");


    
    {
        if (!::linglong::api::client::toStringValue(x_token).isEmpty()) {
            input.headers.insert("X-Token", ::linglong::api::client::toStringValue(x_token));
        }
        }
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
    for (auto keyValueIt = _defaultHeaders.keyValueBegin(); keyValueIt != _defaultHeaders.keyValueEnd(); keyValueIt++) {
        input.headers.insert(keyValueIt->first, keyValueIt->second);
    }
#else
    for (auto key : _defaultHeaders.keys()) {
        input.headers.insert(key, _defaultHeaders[key]);
    }
#endif

    connect(worker, &HttpRequestWorker::on_execution_finished, this, &ClientApi::uploadTaskInfoCallback);
    connect(this, &ClientApi::abortRequestsSignal, worker, &QObject::deleteLater);
    connect(worker, &QObject::destroyed, this, [this]() {
        if (findChildren<HttpRequestWorker*>().count() == 0) {
            Q_EMIT allPendingRequestsCompleted();
        }
    });

    worker->execute(&input);
}

void ClientApi::uploadTaskInfoCallback(HttpRequestWorker *worker) {
    QString error_str = worker->error_str;
    QNetworkReply::NetworkError error_type = worker->error_type;

    if (worker->error_type != QNetworkReply::NoError) {
        error_str = QString("%1, %2").arg(worker->error_str, QString(worker->response));
    }
    UploadTaskInfo_200_response output(QString(worker->response));
    worker->deleteLater();

    if (worker->error_type == QNetworkReply::NoError) {
        Q_EMIT uploadTaskInfoSignal(output);
        Q_EMIT uploadTaskInfoSignalFull(worker, output);
    } else {
        Q_EMIT uploadTaskInfoSignalE(output, error_type, error_str);
        Q_EMIT uploadTaskInfoSignalEFull(worker, error_type, error_str);
    }
}

void ClientApi::uploadTaskLayerFile(const QString &x_token, const QString &task_id, const HttpFileElement &file) {
    QString fullPath = QString(_serverConfigs["uploadTaskLayerFile"][_serverIndices.value("uploadTaskLayerFile")].URL()+"/api/v1/upload-tasks/{task_id}/layer");
    
    
    {
        QString task_idPathParam("{");
        task_idPathParam.append("task_id").append("}");
        QString pathPrefix, pathSuffix, pathDelimiter;
        QString pathStyle = "";
        if (pathStyle == "")
            pathStyle = "simple";
        pathPrefix = getParamStylePrefix(pathStyle);
        pathSuffix = getParamStyleSuffix(pathStyle);
        pathDelimiter = getParamStyleDelimiter(pathStyle, "task_id", false);
        QString paramString = (pathStyle == "matrix") ? pathPrefix+"task_id"+pathSuffix : pathPrefix;
        fullPath.replace(task_idPathParam, paramString+QUrl::toPercentEncoding(::linglong::api::client::toStringValue(task_id)));
    }
    HttpRequestWorker *worker = new HttpRequestWorker(this, _manager);
    worker->setTimeOut(_timeOut);
    worker->setWorkingDirectory(_workingDirectory);
    HttpRequestInput input(fullPath, "PUT");

    
    {
        input.add_file("file", file.local_filename, file.request_filename, file.mime_type);
    }

    
    {
        if (!::linglong::api::client::toStringValue(x_token).isEmpty()) {
            input.headers.insert("X-Token", ::linglong::api::client::toStringValue(x_token));
        }
        }
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
    for (auto keyValueIt = _defaultHeaders.keyValueBegin(); keyValueIt != _defaultHeaders.keyValueEnd(); keyValueIt++) {
        input.headers.insert(keyValueIt->first, keyValueIt->second);
    }
#else
    for (auto key : _defaultHeaders.keys()) {
        input.headers.insert(key, _defaultHeaders[key]);
    }
#endif

    connect(worker, &HttpRequestWorker::on_execution_finished, this, &ClientApi::uploadTaskLayerFileCallback);
    connect(this, &ClientApi::abortRequestsSignal, worker, &QObject::deleteLater);
    connect(worker, &QObject::destroyed, this, [this]() {
        if (findChildren<HttpRequestWorker*>().count() == 0) {
            Q_EMIT allPendingRequestsCompleted();
        }
    });

    worker->execute(&input);
}

void ClientApi::uploadTaskLayerFileCallback(HttpRequestWorker *worker) {
    QString error_str = worker->error_str;
    QNetworkReply::NetworkError error_type = worker->error_type;

    if (worker->error_type != QNetworkReply::NoError) {
        error_str = QString("%1, %2").arg(worker->error_str, QString(worker->response));
    }
    Api_UploadTaskLayerFileResp output(QString(worker->response));
    worker->deleteLater();

    if (worker->error_type == QNetworkReply::NoError) {
        Q_EMIT uploadTaskLayerFileSignal(output);
        Q_EMIT uploadTaskLayerFileSignalFull(worker, output);
    } else {
        Q_EMIT uploadTaskLayerFileSignalE(output, error_type, error_str);
        Q_EMIT uploadTaskLayerFileSignalEFull(worker, error_type, error_str);
    }
}

void ClientApi::tokenAvailable(){

    oauthToken token;
    switch (_OauthMethod) {
    case 1: //implicit flow
        token = _implicitFlow.getToken(_latestScope.join(" "));
        if(token.isValid()){
            _latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
            _latestWorker->execute(&_latestInput);
        }else{
            _implicitFlow.removeToken(_latestScope.join(" "));
            qDebug() << "Could not retrieve a valid token";
        }
        break;
    case 2: //authorization flow
        token = _authFlow.getToken(_latestScope.join(" "));
        if(token.isValid()){
            _latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
            _latestWorker->execute(&_latestInput);
        }else{
            _authFlow.removeToken(_latestScope.join(" "));
            qDebug() << "Could not retrieve a valid token";
        }
        break;
    case 3: //client credentials flow
        token = _credentialFlow.getToken(_latestScope.join(" "));
        if(token.isValid()){
            _latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
            _latestWorker->execute(&_latestInput);
        }else{
            _credentialFlow.removeToken(_latestScope.join(" "));
            qDebug() << "Could not retrieve a valid token";
        }
        break;
    case 4: //resource owner password flow
        token = _passwordFlow.getToken(_latestScope.join(" "));
        if(token.isValid()){
            _latestInput.headers.insert("Authorization", "Bearer " + token.getToken());
            _latestWorker->execute(&_latestInput);
        }else{
            _credentialFlow.removeToken(_latestScope.join(" "));
            qDebug() << "Could not retrieve a valid token";
        }
        break;
    default:
        qDebug() << "No Oauth method set!";
        break;
    }
}
} // namespace linglong
} // namespace api
} // namespace client
