/**
 * OpenAPI Generated Petstore Client
 *
 * This is a sample of Petstore application.
 * 
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

#include "storeapi.h"
#include "qoaiserverconfiguration.h"

#include <QtCore/qanystringview.h>
#include <QtCore/qflags.h>
#include <QtCore/qjsonarray.h>
#include <QtCore/qjsondocument.h>
#include <QtNetwork/qhttpmultipart.h>
#include <QtNetwork/qnetworkaccessmanager.h>
#include <QtNetwork/qnetworkreply.h>
#include <QtNetwork/qnetworkrequestfactory.h>
#include <QtNetwork/qrestaccessmanager.h>

#include <string_view>

using namespace Qt::StringLiterals;
using namespace std::string_view_literals;

using namespace QtOpenApiCommon;

namespace QtOpenAPI {

StoreApi::StoreApi(QObject *parent)
    : QOAIBaseApi(parent)
{
    initializeServerConfigs();
}

StoreApi::~StoreApi()
{
}

void StoreApi::initializeServerConfigs()
{
    //Default server
    QList<QOAIServerConfiguration> defaultConf = QList<QOAIServerConfiguration>();
    //varying endpoint server
    defaultConf.append(QOAIServerConfiguration(
        u"http://127.0.0.1:19080/v2"_s,
        u"No description provided"_s,
        QMap<QString, QOAIServerVariable>()));
    {
        setServersForOperation(u"deleteOrder"_s, defaultConf);
    }
    {
        setServersForOperation(u"getInventory"_s, defaultConf);
    }
    {
        setServersForOperation(u"getOrderById"_s, defaultConf);
    }
    {
        setServersForOperation(u"placeOrder"_s, defaultConf);
    }
}

/**
* \fn void StoreApi::deleteOrder(const QString &orderId)
* 'deleteOrder' operation sends the request to a server.
* The request parameters are defined by a specification file.

* @param[in] orderId QString [required]
*/

/**
* \fn template < Functor, > void StoreApi::deleteOrder(const QString &orderId, const ContextTypeForFunctor< Functor > *context = nullptr, Functor &&callback = (){})
* 'deleteOrder' operation sends the request to a server.
* The request parameters are defined by a specification file.
*
* \attention Use the operation with following parameters in the callback:
* \code {c++}
*    deleteOrder(orderId, this, [&](const QRestReply &reply) { if (reply.isSuccess()) ... });
* \endcode

* @param[in] orderId QString [required]
* @param[in] context const ContextTypeForFunctor< Functor > * [optional]
* @param[in] callback Functor && [optional]
*/

/**
* \fn void StoreApi::deleteOrderCallback(const QRestReply &reply)
* Processes a \a reply response from a server.
* The result of processed data is emitted by deleteOrderFinished() or
* being returned as a callback parameter of deleteOrder() request.
* @param[in] reply const QRestReply &
*/

/**
* \fn void StoreApi::deleteOrderWithDataImpl(const QString &orderId, const QObject *context, QtPrivate::QSlotObjectBase *slot)
* Implements the deleteOrder() operation request.

* @param[in] orderId QString [required]
* @param[in] context const QObject * [optional]
* @param[in] slot QtPrivate::QSlotObjectBase * [optional]
*/
void StoreApi::deleteOrderWithDataImpl(const QString &orderId, const QObject *context, QtPrivate::QSlotObjectBase *slot)
{
    QtPrivate::SlotObjUniquePtr slotPtr(slot);
    setBaseServerUrl(u"deleteOrder"_s);
    QString fullPath = u"/store/order/{orderId}"_s;
    {
        QString orderIdPathParam = u"{%1}"_s.arg(u"orderId"_s);

        SerializationFlags flags;
        flags.setFlag(SerializationFlag::Object, false || false);
        flags.setFlag(SerializationFlag::NeedPercentEncoding, true);
        flags.setFlag(SerializationFlag::Explode, false);

        SerializationOptions opts;
        opts.style = "simple"sv.empty() ? "simple" : "simple";
        opts.prefix = getParamStylePrefix(opts.style);
        opts.delimiter = getParamStyleDelimiter(opts.style, flags);
        opts.assignOperator = getParamStyleAssignOperator(opts.style, flags);
        opts.suffix = getParamStyleSuffix(opts.style, QUrl::toPercentEncoding(u"orderId"_s), flags);
        opts.flags = flags;
        QString paramString = opts.prefix + opts.suffix;
        paramString += QUrl::toPercentEncoding(::QtOpenApiCommon::toStringValue(orderId));
        // In case style=matrix and paramString is empty due to any reasons,
        // we serialize it like undefined value and delete '='.
        // Described here: https://spec.openapis.org/oas/v3.1.1.html#style-values
        if ((paramString == opts.prefix + opts.suffix) && opts.style == "matrix")
            paramString.chop(1);
        fullPath.replace(orderIdPathParam, paramString);
    }

    QOAIHttpRequestInput input(fullPath, "DELETE"_L1);
    QByteArray requestContent;
    QNetworkRequest request
        = QOAIHttpRequestWorker::getNetworkRequest(input, requestContent,
                                                         networkRequestFactory(),
                                                         responseCompressionEnabled(),
                                                         requestCompressionEnabled());
    QNetworkReply *reply = execute(input, request, requestContent);
    if (reply != nullptr) {
        reply->setParent(this);
        setCallerInfo(reply, QOAICallerInfo{context, QtPrivate::SlotObjSharedPtr(std::move(slotPtr))});
        connect(reply, &QNetworkReply::finished, this, [this, reply] {
            deleteOrderCallback(QRestReply(reply));
        });
        connect(reply, &QNetworkReply::errorOccurred, this, [this, reply] {
            if (reply) {
                emit deleteOrderErrorOccurred(reply->error(), reply->errorString());
                QOAICallerInfo callerInfo = takeCallerInfo(reply);
                if (callerInfo.slot) {
                    QRestReply restRepl(reply);
                    void *argv[] = { nullptr, &restRepl };
                    QObject *context = callerInfo.contextObject ? const_cast<QObject*>(callerInfo.contextObject.get()) : nullptr;
                    callerInfo.slot->call(context, argv);
                }
            }
        });
    }
}

void StoreApi::deleteOrderCallback(const QRestReply &reply)
{
    auto netReply = reply.networkReply();
    if (netReply)
        netReply->disconnect(this);
    if (!reply.isSuccess())
        return;

    // Check if callback is provided
    QOAICallerInfo callerInfo = takeCallerInfo(netReply);
    if (callerInfo.slot) {
        void *argv[] = { nullptr, const_cast<QRestReply*>(&reply) };
        QObject *context = callerInfo.contextObject
                        ? const_cast<QObject*>(callerInfo.contextObject.get()) : nullptr;
        callerInfo.slot->call(context, argv);
    }
    emit deleteOrderFinished();
}

/**
* \fn void StoreApi::getInventory()
* 'getInventory' operation sends the request to a server.
* The request parameters are defined by a specification file.

*/

/**
* \fn template < Functor, > void StoreApi::getInventory(const ContextTypeForFunctor< Functor > *context = nullptr, Functor &&callback = (){})
* 'getInventory' operation sends the request to a server.
* The request parameters are defined by a specification file.
*
* \attention Use the operation with following parameters in the callback:
* \code {c++}
*    getInventory(this, [&](const QRestReply &reply, const QMap<QString, qint32> &summary) { if (reply.isSuccess()) ... });
* \endcode

* @param[in] context const ContextTypeForFunctor< Functor > * [optional]
* @param[in] callback Functor && [optional]
*/

/**
* \fn void StoreApi::getInventoryCallback(const QRestReply &reply)
* Processes a \a reply response from a server.
* The result of processed data is emitted by getInventoryFinished() or
* being returned as a callback parameter of getInventory() request.
* @param[in] reply const QRestReply &
*/

/**
* \fn void StoreApi::getInventoryWithDataImpl(const QObject *context, QtPrivate::QSlotObjectBase *slot)
* Implements the getInventory() operation request.

* @param[in] context const QObject * [optional]
* @param[in] slot QtPrivate::QSlotObjectBase * [optional]
*/
void StoreApi::getInventoryWithDataImpl(const QObject *context, QtPrivate::QSlotObjectBase *slot)
{
    QtPrivate::SlotObjUniquePtr slotPtr(slot);
    setBaseServerUrl(u"getInventory"_s);
    QString fullPath = u"/store/inventory"_s;
    if (const auto key = apiKey("api_key"_L1); key.has_value()) {
        setHeader("api_key"_L1, *key);
    }

    QOAIHttpRequestInput input(fullPath, "GET"_L1);
    QByteArray requestContent;
    QNetworkRequest request
        = QOAIHttpRequestWorker::getNetworkRequest(input, requestContent,
                                                         networkRequestFactory(),
                                                         responseCompressionEnabled(),
                                                         requestCompressionEnabled());
    QNetworkReply *reply = execute(input, request, requestContent);
    if (reply != nullptr) {
        reply->setParent(this);
        setCallerInfo(reply, QOAICallerInfo{context, QtPrivate::SlotObjSharedPtr(std::move(slotPtr))});
        connect(reply, &QNetworkReply::finished, this, [this, reply] {
            getInventoryCallback(QRestReply(reply));
        });
        connect(reply, &QNetworkReply::errorOccurred, this, [this, reply] {
            if (reply) {
                emit getInventoryErrorOccurred(reply->error(), reply->errorString());
                QOAICallerInfo callerInfo = takeCallerInfo(reply);
                if (callerInfo.slot) {
                    QMap<QString, qint32> empty;
                    QRestReply restRepl(reply);
                    void *argv[] = { nullptr, &restRepl, &empty };
                    QObject *context = callerInfo.contextObject ? const_cast<QObject*>(callerInfo.contextObject.get()) : nullptr;
                    callerInfo.slot->call(context, argv);
                }
            }
        });
    }
}

void StoreApi::getInventoryCallback(const QRestReply &reply)
{
    auto netReply = reply.networkReply();
    if (netReply)
        netReply->disconnect(this);
    if (!reply.isSuccess())
        return;

    const QByteArray response = QOAIHttpRequestWorker::parseResponse(reply, workingDirectory());
    QMap<QString, qint32> output;
    const QJsonDocument doc = QJsonDocument::fromJson(response);
    if (!doc.isNull() && doc.isObject()) {
        const QJsonObject obj = doc.object();
        for (const QString &key : obj.keys()) {
            qint32 val;
            const bool ok = ::QtOpenApiCommon::fromJsonValue(val, obj[key]);
            if (!ok)
                qWarning("%s: Failed to convert QJsonValue to qint32.", Q_FUNC_INFO);
            output.insert(key, val);
        }
    } else {
        qWarning("%s: Failed to parse the response as a JSON object.", Q_FUNC_INFO);
    }
    // Check if callback is provided
    QOAICallerInfo callerInfo = takeCallerInfo(netReply);
    if (callerInfo.slot) {
        void *argv[] = { nullptr, const_cast<QRestReply*>(&reply), &output };
        QObject *context = callerInfo.contextObject
                        ? const_cast<QObject*>(callerInfo.contextObject.get()) : nullptr;
        callerInfo.slot->call(context, argv);
    }
    emit getInventoryFinished(output);
}

/**
* \fn void StoreApi::getOrderById(const qint64 &orderId)
* 'getOrderById' operation sends the request to a server.
* The request parameters are defined by a specification file.

* @param[in] orderId qint64 [required]
*/

/**
* \fn template < Functor, > void StoreApi::getOrderById(const qint64 &orderId, const ContextTypeForFunctor< Functor > *context = nullptr, Functor &&callback = (){})
* 'getOrderById' operation sends the request to a server.
* The request parameters are defined by a specification file.
*
* \attention Use the operation with following parameters in the callback:
* \code {c++}
*    getOrderById(orderId, this, [&](const QRestReply &reply, const Order &summary) { if (reply.isSuccess()) ... });
* \endcode

* @param[in] orderId qint64 [required]
* @param[in] context const ContextTypeForFunctor< Functor > * [optional]
* @param[in] callback Functor && [optional]
*/

/**
* \fn void StoreApi::getOrderByIdCallback(const QRestReply &reply)
* Processes a \a reply response from a server.
* The result of processed data is emitted by getOrderByIdFinished() or
* being returned as a callback parameter of getOrderById() request.
* @param[in] reply const QRestReply &
*/

/**
* \fn void StoreApi::getOrderByIdWithDataImpl(const qint64 &orderId, const QObject *context, QtPrivate::QSlotObjectBase *slot)
* Implements the getOrderById() operation request.

* @param[in] orderId qint64 [required]
* @param[in] context const QObject * [optional]
* @param[in] slot QtPrivate::QSlotObjectBase * [optional]
*/
void StoreApi::getOrderByIdWithDataImpl(const qint64 &orderId, const QObject *context, QtPrivate::QSlotObjectBase *slot)
{
    QtPrivate::SlotObjUniquePtr slotPtr(slot);
    setBaseServerUrl(u"getOrderById"_s);
    QString fullPath = u"/store/order/{orderId}"_s;
    {
        QString orderIdPathParam = u"{%1}"_s.arg(u"orderId"_s);

        SerializationFlags flags;
        flags.setFlag(SerializationFlag::Object, false || false);
        flags.setFlag(SerializationFlag::NeedPercentEncoding, true);
        flags.setFlag(SerializationFlag::Explode, false);

        SerializationOptions opts;
        opts.style = "simple"sv.empty() ? "simple" : "simple";
        opts.prefix = getParamStylePrefix(opts.style);
        opts.delimiter = getParamStyleDelimiter(opts.style, flags);
        opts.assignOperator = getParamStyleAssignOperator(opts.style, flags);
        opts.suffix = getParamStyleSuffix(opts.style, QUrl::toPercentEncoding(u"orderId"_s), flags);
        opts.flags = flags;
        QString paramString = opts.prefix + opts.suffix;
        paramString += QUrl::toPercentEncoding(::QtOpenApiCommon::toStringValue(orderId));
        // In case style=matrix and paramString is empty due to any reasons,
        // we serialize it like undefined value and delete '='.
        // Described here: https://spec.openapis.org/oas/v3.1.1.html#style-values
        if ((paramString == opts.prefix + opts.suffix) && opts.style == "matrix")
            paramString.chop(1);
        fullPath.replace(orderIdPathParam, paramString);
    }

    QOAIHttpRequestInput input(fullPath, "GET"_L1);
    QByteArray requestContent;
    QNetworkRequest request
        = QOAIHttpRequestWorker::getNetworkRequest(input, requestContent,
                                                         networkRequestFactory(),
                                                         responseCompressionEnabled(),
                                                         requestCompressionEnabled());
    QNetworkReply *reply = execute(input, request, requestContent);
    if (reply != nullptr) {
        reply->setParent(this);
        setCallerInfo(reply, QOAICallerInfo{context, QtPrivate::SlotObjSharedPtr(std::move(slotPtr))});
        connect(reply, &QNetworkReply::finished, this, [this, reply] {
            getOrderByIdCallback(QRestReply(reply));
        });
        connect(reply, &QNetworkReply::errorOccurred, this, [this, reply] {
            if (reply) {
                emit getOrderByIdErrorOccurred(reply->error(), reply->errorString());
                QOAICallerInfo callerInfo = takeCallerInfo(reply);
                if (callerInfo.slot) {
                    Order empty;
                    QRestReply restRepl(reply);
                    void *argv[] = { nullptr, &restRepl, &empty };
                    QObject *context = callerInfo.contextObject ? const_cast<QObject*>(callerInfo.contextObject.get()) : nullptr;
                    callerInfo.slot->call(context, argv);
                }
            }
        });
    }
}

void StoreApi::getOrderByIdCallback(const QRestReply &reply)
{
    auto netReply = reply.networkReply();
    if (netReply)
        netReply->disconnect(this);
    if (!reply.isSuccess())
        return;

    const QByteArray response = QOAIHttpRequestWorker::parseResponse(reply, workingDirectory());
    Order output(response);
    // Check if callback is provided
    QOAICallerInfo callerInfo = takeCallerInfo(netReply);
    if (callerInfo.slot) {
        void *argv[] = { nullptr, const_cast<QRestReply*>(&reply), &output };
        QObject *context = callerInfo.contextObject
                        ? const_cast<QObject*>(callerInfo.contextObject.get()) : nullptr;
        callerInfo.slot->call(context, argv);
    }
    emit getOrderByIdFinished(output);
}

/**
* \fn void StoreApi::placeOrder(const Order &order)
* 'placeOrder' operation sends the request to a server.
* The request parameters are defined by a specification file.

* @param[in] order Order [required]
*/

/**
* \fn template < Functor, > void StoreApi::placeOrder(const Order &order, const ContextTypeForFunctor< Functor > *context = nullptr, Functor &&callback = (){})
* 'placeOrder' operation sends the request to a server.
* The request parameters are defined by a specification file.
*
* \attention Use the operation with following parameters in the callback:
* \code {c++}
*    placeOrder(order, this, [&](const QRestReply &reply, const Order &summary) { if (reply.isSuccess()) ... });
* \endcode

* @param[in] order Order [required]
* @param[in] context const ContextTypeForFunctor< Functor > * [optional]
* @param[in] callback Functor && [optional]
*/

/**
* \fn void StoreApi::placeOrderCallback(const QRestReply &reply)
* Processes a \a reply response from a server.
* The result of processed data is emitted by placeOrderFinished() or
* being returned as a callback parameter of placeOrder() request.
* @param[in] reply const QRestReply &
*/

/**
* \fn void StoreApi::placeOrderWithDataImpl(const Order &order, const QObject *context, QtPrivate::QSlotObjectBase *slot)
* Implements the placeOrder() operation request.

* @param[in] order Order [required]
* @param[in] context const QObject * [optional]
* @param[in] slot QtPrivate::QSlotObjectBase * [optional]
*/
void StoreApi::placeOrderWithDataImpl(const Order &order, const QObject *context, QtPrivate::QSlotObjectBase *slot)
{
    QtPrivate::SlotObjUniquePtr slotPtr(slot);
    setBaseServerUrl(u"placeOrder"_s);
    QString fullPath = u"/store/order"_s;

    QOAIHttpRequestInput input(fullPath, "POST"_L1);
    input.headers().replaceOrAppend(QHttpHeaders::WellKnownHeader::ContentType, "application/json"_L1);
    {
        const QByteArray output = order.asJson().toUtf8();
        input.setRequestBody(output);
    }
    QByteArray requestContent;
    QNetworkRequest request
        = QOAIHttpRequestWorker::getNetworkRequest(input, requestContent,
                                                         networkRequestFactory(),
                                                         responseCompressionEnabled(),
                                                         requestCompressionEnabled());
    QNetworkReply *reply = execute(input, request, requestContent);
    if (reply != nullptr) {
        reply->setParent(this);
        setCallerInfo(reply, QOAICallerInfo{context, QtPrivate::SlotObjSharedPtr(std::move(slotPtr))});
        connect(reply, &QNetworkReply::finished, this, [this, reply] {
            placeOrderCallback(QRestReply(reply));
        });
        connect(reply, &QNetworkReply::errorOccurred, this, [this, reply] {
            if (reply) {
                emit placeOrderErrorOccurred(reply->error(), reply->errorString());
                QOAICallerInfo callerInfo = takeCallerInfo(reply);
                if (callerInfo.slot) {
                    Order empty;
                    QRestReply restRepl(reply);
                    void *argv[] = { nullptr, &restRepl, &empty };
                    QObject *context = callerInfo.contextObject ? const_cast<QObject*>(callerInfo.contextObject.get()) : nullptr;
                    callerInfo.slot->call(context, argv);
                }
            }
        });
    }
}

void StoreApi::placeOrderCallback(const QRestReply &reply)
{
    auto netReply = reply.networkReply();
    if (netReply)
        netReply->disconnect(this);
    if (!reply.isSuccess())
        return;

    const QByteArray response = QOAIHttpRequestWorker::parseResponse(reply, workingDirectory());
    Order output(response);
    // Check if callback is provided
    QOAICallerInfo callerInfo = takeCallerInfo(netReply);
    if (callerInfo.slot) {
        void *argv[] = { nullptr, const_cast<QRestReply*>(&reply), &output };
        QObject *context = callerInfo.contextObject
                        ? const_cast<QObject*>(callerInfo.contextObject.get()) : nullptr;
        callerInfo.slot->call(context, argv);
    }
    emit placeOrderFinished(output);
}

} // namespace QtOpenAPI
