/**
 * Qt6 Common library
 *
 * Copyright (C) 2026 The Qt Company Ltd.
 * SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

#ifndef QOAI_BASEAPI_H
#define QOAI_BASEAPI_H

#include "qoaicmakecommonlibgeneratedclientcommonexports.h"
#include "qoaihelpers.h"
#include "qoaihttprequest.h"
#include "qoaiserverconfiguration.h"
#include "qoaiservervariable.h"

#include <QtCore/qanystringview.h>
#include <QtCore/qcontainerfwd.h>
#include <QtCore/qobject.h>
#include <QtCore/qpointer.h>

#include <QtNetwork/qhttpheaders.h>
#include <QtNetwork/qnetworkrequestfactory.h>
#if QT_CONFIG(ssl)
#include <QtNetwork/qsslconfiguration.h>
#endif // ssl

#include <memory>
#include <optional>

QT_BEGIN_NAMESPACE
class QNetworkAccessManager;
class QNetworkReply;
class QRestAccessManager;
QT_END_NAMESPACE

/*! is a list of typed data. */
#define QOAI_VA_LIST(...) __VA_ARGS__
/**
* \def QOAI_ADD_EMPTY_OPERATION_IMPL(OPERATION, DEPRECATED)
* Add an OPERATION with no input arguments and without any additional datatype content
* responded by the server. The expected OPERATION response is HTTP code.
*
* See ./doc/html/index.html for operations implementation details.
*
* @param[in] OPERATION - the API name that will be added by this macro.
* @param[in] DEPRECATED - sets Q_DECL_DEPRECATED if operation is deprecated.
**/
#define QOAI_ADD_EMPTY_OPERATION_IMPL(OPERATION, DEPRECATED)                      \
public:                                                                                 \
Q_INVOKABLE DEPRECATED void OPERATION()                                                 \
{                                                                                       \
    OPERATION##WithDataImpl(nullptr, nullptr);                                          \
}                                                                                       \
protected:                                                                              \
void OPERATION##WithDataImpl(const QObject *_qt_context, QtPrivate::QSlotObjectBase *_qt_slot); \
void OPERATION##Callback(const QRestReply &_qt_reply);                                      \
public:                                                                                 \
template <typename Functor, if_compatible_callback<Functor> = true>                     \
DEPRECATED void OPERATION(const ContextTypeForFunctor<Functor> *_qt_context, Functor &&_qt_callback)       \
{                                                                                                  \
    OPERATION##WithDataImpl(_qt_context,                                                               \
    QtPrivate::makeCallableObject<QOAIEmptyCallbackReply>(std::forward<Functor>(_qt_callback))); \
}                                                                                                  \

/**
* \def QOAI_ADD_NO_PARAMS_OPERATION_WITH_RESPONSE_IMPL(OPERATION, RESPONSE, DEPRECATED)
* Add an OPERATION with no input arguments, but with RESPONSE datatypes responded by the server.
*
* See ./doc/html/index.html for operations implementation details.
*
* @param[in] OPERATION - the API name that will be added by this macro.
* @param[in] RESPONSE  - the list objects that the server provides as a response to the OPERATION call.
* @param[in] DEPRECATED - sets Q_DECL_DEPRECATED if operation is deprecated.
**/
#define QOAI_ADD_NO_PARAMS_OPERATION_WITH_RESPONSE_IMPL(OPERATION, RESPONSE, DEPRECATED)       \
public:                                                                                              \
Q_INVOKABLE DEPRECATED void OPERATION()                                                              \
{                                                                                                    \
    OPERATION##WithDataImpl(nullptr, nullptr);                                                       \
}                                                                                                    \
protected:                                                                                           \
using OPERATION##CallbackReply = void(*)(const QRestReply &, QOAI_VA_LIST RESPONSE);           \
template <typename Functor>                                                                          \
using OPERATION##_compatible_callback =                                                              \
std::enable_if_t<QtPrivate::AreFunctionsCompatible<OPERATION##CallbackReply, Functor>::value, bool>; \
void OPERATION##WithDataImpl(const QObject *_qt_context, QtPrivate::QSlotObjectBase *_qt_slot);        \
void OPERATION##Callback(const QRestReply &_qt_reply);                                             \
public:                                                                                        \
template <typename Functor, OPERATION##_compatible_callback<Functor> = true>                   \
DEPRECATED void OPERATION(const ContextTypeForFunctor<Functor> *_qt_context, Functor &&_qt_callback)   \
{                                                                                              \
    OPERATION##WithDataImpl(_qt_context,                                                           \
    QtPrivate::makeCallableObject<OPERATION##CallbackReply>(std::forward<Functor>(_qt_callback))); \
}                                                                                              \

/**
* \def QOAI_ADD_OPERATION_IMPL(OPERATION, PARAMS, ARGS, RESPONSE, DEPRECATED)
* Add an OPERATION with input parameters PARAMS and arguments ARGS and with RESPONSE datatypes
* responded by the server.
*
* See ./doc/html/index.html for operations implementation details.
*
* @param[in] OPERATION - the API name that will be added by this macro.
* @param[in] PARAMS    - the list of OPERATION data types.
* @param[in] ARGS      - the list of OPERATION arguments.
* @param[in] RESPONSE  - the list objects that the server provides as a response to the OPERATION call.
* @param[in] DEPRECATED - sets Q_DECL_DEPRECATED if operation is deprecated.
**/
#define QOAI_ADD_OPERATION_IMPL(OPERATION, PARAMS, ARGS, RESPONSE, DEPRECATED)      \
public:                                                                                   \
Q_INVOKABLE DEPRECATED void OPERATION(QOAI_VA_LIST PARAMS)                          \
{                                                                                         \
    OPERATION##WithDataImpl(QOAI_VA_LIST ARGS, nullptr, nullptr);                   \
}                                                                                         \
protected:                                                                                \
void OPERATION##WithDataImpl(QOAI_VA_LIST PARAMS, const QObject *_qt_context = nullptr, \
                            QtPrivate::QSlotObjectBase *_qt_slot = nullptr);                  \
void OPERATION##Callback(const QRestReply &_qt_reply);                                        \
using OPERATION##CallbackReply = void(*)(const QRestReply &, QOAI_VA_LIST RESPONSE);           \
template <typename Functor>                                                                          \
using OPERATION##_compatible_callback =                                                              \
std::enable_if_t<QtPrivate::AreFunctionsCompatible<OPERATION##CallbackReply, Functor>::value, bool>; \
public:                                                                                              \
template <typename Functor, OPERATION##_compatible_callback<Functor> = true>                         \
DEPRECATED void OPERATION(QOAI_VA_LIST PARAMS, const ContextTypeForFunctor<Functor> *_qt_context = nullptr,   \
                    Functor &&_qt_callback = [](const QRestReply &, QOAI_VA_LIST RESPONSE){})      \
{                                                                                                    \
    OPERATION##WithDataImpl(QOAI_VA_LIST ARGS, _qt_context,                                        \
    QtPrivate::makeCallableObject<OPERATION##CallbackReply>(std::forward<Functor>(_qt_callback)));       \
}                                                                                                    \

/**
* \def QOAI_ADD_OPERATION_WITH_NO_RESPONSE_IMPL(OPERATION, PARAMS, ARGS, DEPRECATED)
* Add an OPERATION with input arguments ARGS, but without any additional datatype content
* responded by the server. The expected OPERATION response is HTTP code.
*
* See ./doc/html/index.html for operations implementation details.
*
* @param[in] OPERATION - the API name that will be added by this macro.
* @param[in] PARAMS    - the list of OPERATION data types.
* @param[in] ARGS      - the list of OPERATION arguments.
* @param[in] DEPRECATED - sets Q_DECL_DEPRECATED if operation is deprecated.
**/
#define QOAI_ADD_OPERATION_WITH_NO_RESPONSE_IMPL(OPERATION, PARAMS, ARGS, DEPRECATED)                      \
public:                                                                                                          \
Q_INVOKABLE DEPRECATED void OPERATION(QOAI_VA_LIST PARAMS)                          \
{                                                                                         \
    OPERATION##WithDataImpl(QOAI_VA_LIST ARGS, nullptr, nullptr);                   \
}                                                                                         \
protected:                                                                                \
void OPERATION##WithDataImpl(QOAI_VA_LIST PARAMS, const QObject *_qt_context = nullptr, \
                            QtPrivate::QSlotObjectBase *_qt_slot = nullptr);                  \
void OPERATION##Callback(const QRestReply &_qt_reply);                                        \
public:                                                                                   \
template <typename Functor, if_compatible_callback<Functor> = true>                       \
DEPRECATED void OPERATION(QOAI_VA_LIST PARAMS, const ContextTypeForFunctor<Functor> *_qt_context = nullptr, \
                    Functor &&_qt_callback = [](const QRestReply &){})                              \
{                                                                                         \
    OPERATION##WithDataImpl(QOAI_VA_LIST ARGS, _qt_context,                             \
    QtPrivate::makeCallableObject<QOAIEmptyCallbackReply>(std::forward<Functor>(_qt_callback))); \
}                                                                                                  \

QT_BEGIN_NAMESPACE

namespace QtOpenApiCommon {

class QOAIBaseApiPrivate;

class CMAKECOMMONLIBGENERATEDCLIENT_COMMON_EXPORT QOAIBaseApi : public QObject {
    Q_OBJECT

    Q_PROPERTY(QList<QString> operations READ operations)
    Q_PROPERTY(QString bearerToken READ bearerToken WRITE setBearerToken)
    Q_PROPERTY(QString username READ username WRITE setUsername)
    Q_PROPERTY(QString password READ password WRITE setPassword)
    Q_PROPERTY(QString workingDirectory READ workingDirectory WRITE setWorkingDirectory)
    Q_PROPERTY(bool requestCompressionEnabled READ requestCompressionEnabled  WRITE setRequestCompressionEnabled)
    Q_PROPERTY(bool responseCompressionEnabled READ responseCompressionEnabled  WRITE setResponseCompressionEnabled)

public:
    using ServerError = QOAIServerVariable::ServerError;
    Q_ENUM(ServerError)

    using FileConflictPolicy = QOAIFileConflictPolicy;

    QOAIBaseApi() : QOAIBaseApi(nullptr) {}
    explicit QOAIBaseApi(QObject *parent);
    ~QOAIBaseApi() override;

public:
    QList<QString> operations() const;
    QList<QOAIServerConfiguration> serverConfigurations(const QString &operation) const;

    ServerError setServerVariable(const QString &operation, qsizetype serverIndex,
                                  const QString &variable, const QString &value);
    ServerError setServer(const QString &operation, qsizetype serverIndex);
    std::optional<qsizetype> activeServer(const QString &operation) const;

    Q_INVOKABLE void setApiKey(const QString &apiKeyName, const QString &apiKey);
    std::optional<QString> apiKey(const QString &name) const;
    void setBearerToken(const QString &token);
    QString bearerToken() const;
    void setUsername(const QString &username);
    QString username() const;
    void setPassword(const QString &password);
    QString password() const;
    Q_INVOKABLE void setTimeOut(std::chrono::milliseconds timeOut);
#if QT_CONFIG(ssl)
    void setSslConfiguration(QSslConfiguration config);
    QSslConfiguration sslConfiguration() const;
#endif // ssl
    void setWorkingDirectory(const QString &path);
    QString workingDirectory() const;
    void setRestAccessManager(QRestAccessManager *ram);
    QRestAccessManager *restAccessManager() const;
    void setNetworkRequestFactory(QNetworkRequestFactory factory);
    QNetworkRequestFactory networkRequestFactory() const;

    void setHeader(QHttpHeaders::WellKnownHeader key, QAnyStringView value);
    Q_INVOKABLE void setHeader(QAnyStringView key, QAnyStringView value);

    void setRequestCompressionEnabled(bool enabled);
    bool requestCompressionEnabled() const;
    void setResponseCompressionEnabled(bool enabled);
    bool responseCompressionEnabled() const;

    void setFileConflictPolicy(FileConflictPolicy policy);
    FileConflictPolicy fileConflictPolicy() const;

    void setDecompressedSafetyCheckThreshold(qint64 threshold);
    qint64 decompressedSafetyCheckThreshold() const;

    QString errorString(ServerError error) const;

protected:
    struct QOAICallerInfo
    {
        QPointer<const QObject> contextObject = nullptr;
        QtPrivate::SlotObjSharedPtr slot;
    };
    using QOAIEmptyCallbackReply = void(*)(QRestReply&);
    template <typename Functor>
    using ContextTypeForFunctor = typename QtPrivate::ContextTypeForFunctor<Functor>::ContextType;
    template <typename Functor>
    using if_compatible_callback = std::enable_if_t<QtPrivate::AreFunctionsCompatible<QOAIEmptyCallbackReply, Functor>::value, bool>;

    QNetworkReply *execute(QOAIHttpRequestInput &input, QNetworkRequest &request, QByteArray &requestContent);
    void setServersForOperation(const QString &operation, const QList<QOAIServerConfiguration> &configs);
    void setBaseServerUrl(const QString &operation);
    void setCallerInfo(QNetworkReply *reply, const QOAICallerInfo &info);
    QOAICallerInfo takeCallerInfo(QNetworkReply *reply);

private:
    // Note that d_ptr refers to QObjectPrivate, which we cannot use because
    // we do not want to link to CorePrivate
    friend class QOAIBaseApiPrivate;
    std::unique_ptr<QOAIBaseApiPrivate> d;
};

} // namespace QtOpenApiCommon

QT_END_NAMESPACE

#endif

