#ifndef SBK_KPROCESSWRAPPER_H
#define SBK_KPROCESSWRAPPER_H

// Workaround to access protected functions
#ifndef protected
#  define protected public
#endif

#include <kprocess.h>

#include <sbkpython.h>

#include <array>
namespace Shiboken { struct AutoDecRef; class GilState; }

namespace PySide { class DynamicQMetaObject; }

class KProcessWrapper : public KProcess
{
public:
    KProcessWrapper(::QObject * parent = nullptr);
    KProcessWrapper(const KProcessWrapper &) = delete;
    KProcessWrapper& operator=(const KProcessWrapper &) = delete;
    KProcessWrapper(KProcessWrapper &&) = delete;
    KProcessWrapper& operator=(KProcessWrapper &&) = delete;
    ~KProcessWrapper() override;

    bool atEnd() const override;
    static bool sbk_o_atEnd([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride);
    qint64 bytesAvailable() const override;
    static qint64 sbk_o_bytesAvailable([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride);
    qint64 bytesToWrite() const override;
    bool canReadLine() const override;
    void childEvent(::QChildEvent * event) override;
    void close() override;
    static void sbk_o_close([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride);
    void connectNotify(const ::QMetaMethod & signal) override;
    void customEvent(::QEvent * event) override;
    void disconnectNotify(const ::QMetaMethod & signal) override;
    bool event(::QEvent * event) override;
    bool eventFilter(::QObject * watched, ::QEvent * event) override;
    bool isSequential() const override;
    bool open(::QFlags<QIODeviceBase::OpenModeFlag> mode = QIODeviceBase::OpenModeFlag::ReadWrite) override;
    static bool sbk_o_open([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] ::QFlags<QIODeviceBase::OpenModeFlag> mode = QIODeviceBase::OpenModeFlag::ReadWrite);
    qint64 pos() const override;
    qint64 readData(char * data, qint64 maxlen) override;
    static qint64 sbk_o_readData([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] char * data, [[maybe_unused]] qint64 maxlen);
    qint64 readLineData(char * data, qint64 maxlen) override;
    static qint64 sbk_o_readLineData([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] char * data, [[maybe_unused]] qint64 maxlen);
    bool reset() override;
    bool seek(qint64 pos) override;
    static bool sbk_o_seek([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] qint64 pos);
    qint64 size() const override;
    qint64 skipData(qint64 maxSize) override;
    static qint64 sbk_o_skipData([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] qint64 maxSize);
    void timerEvent(::QTimerEvent * event) override;
    bool waitForBytesWritten(int msecs = 30000) override;
    static bool sbk_o_waitForBytesWritten([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] int msecs = 30000);
    bool waitForReadyRead(int msecs = 30000) override;
    static bool sbk_o_waitForReadyRead([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] int msecs = 30000);
    qint64 writeData(const char * data, qint64 len) override;
    static qint64 sbk_o_writeData([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] const char * data, [[maybe_unused]] qint64 len);

    const ::QMetaObject * metaObject() const override;
    int qt_metacall(QMetaObject::Call call, int id, void **args) override;
    void *qt_metacast(const char *_clname) override;
    static void pysideInitQtMetaTypes();

    void resetPyMethodCache();

private:
    mutable std::array<PyObject *, 24> m_PyMethodCache = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
};

#endif // SBK_KPROCESSWRAPPER_H
