/*
 * SPDX-FileCopyrightText: 2026 Oak Ridge National Laboratory and Contributors
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef ADIOS2_OPERATOR_PLUGIN_PLUGINOPERATOR_H_
#define ADIOS2_OPERATOR_PLUGIN_PLUGINOPERATOR_H_

#include "adios2/plugin/PluginOperatorInterface.h"

#include <memory> // for unique_ptr
#include <string> // for string

#include "adios2/common/ADIOSTypes.h"
#include "adios2/core/Operator.h"

namespace adios2
{
namespace plugin
{

/** A front-end wrapper for an operator implemented outside of libadios2 */
class PluginOperator : public core::Operator
{
public:
    PluginOperator(const Params &parameters);
    virtual ~PluginOperator();

    size_t GetEstimatedSize(const size_t ElemCount, const size_t ElemSize, const size_t ndims,
                            const size_t *dims) const override;

    void AddExtraParameters(const Params &params) override;
    size_t Operate(const char *dataIn, const Dims &blockStart, const Dims &blockCount,
                   const DataType type, char *bufferOut) override;

    size_t InverseOperate(const char *bufferIn, const size_t sizeIn, char *dataOut) override;

    bool IsDataTypeValid(const DataType type) const override;

    std::string m_PluginLibrary;
    std::string m_PluginName;
    bool m_OperatorNameQuery = false;

protected:
    void PluginInit(const std::string &pluginName, const std::string &pluginLibrary);

private:
    struct Impl;
    std::unique_ptr<Impl> m_Impl;
    Params m_ExtraParams;
};

} // end namespace plugin
} // end namespace adios2

#endif /* ADIOS2_OPERATOR_PLUGIN_PLUGINOPERATOR_H_ */
