/* Subscriber interface
Copyright (C) 2020 Jonathan Hanks

This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef LIBCDS_PUBSUB_PUB_PLUGIN_HH
#define LIBCDS_PUBSUB_PUB_PLUGIN_HH

#include <memory>
#include <string>
#include <cds-pubsub/common.hh>

namespace pub_sub
{
    namespace plugins
    {
        /*!
         * @brief the PublisherInstance is the base class which all publishing
         * plugins must implement.
         */
        class PublisherInstance
        {
        public:
            virtual ~PublisherInstance( ) = default;
            /*!
             * @brief The message publishing interface
             * @param key Message key
             * @param msg Message data
             */
            virtual void publish( KeyType key, Message msg ) = 0;
        };
        using UniquePublisherInstance = std::unique_ptr< PublisherInstance >;

        /*!
         * @brief A plugin api which provides a way to create PublisherInstances
         */
        class PublisherPluginApi
        {
        public:
            virtual ~PublisherPluginApi( ) = default;

            /*!
             * @brief Returns the prefix (tcp:// or udp:// or ...) that
             * corresponds to this plugin
             * @return The prefix for the plugin
             */
            virtual const std::string& prefix( ) const = 0;
            /*!
             * @brief plugin version
             * @return version as a string
             */
            virtual const std::string& version( ) const = 0;
            /*!
             * @brief plugin name
             * @return name as a string
             */
            virtual const std::string& name( ) const = 0;

            /*!
             * @brief Create a PublisherInstance that can publish to the given
             * address
             * @note it is assumed that the caller has checked that address
             * begins with prefix()
             * @param address The address to create a PublisherInstance for
             * @param debug_hooks
             * @return A unique_ptr to the PublisherInstance that can handle
             * address
             */
            virtual UniquePublisherInstance
            publish( const std::string&      address,
                     PubDebugNotices&        debug_hooks,
                     UniquePublisherInstance next_stage ) = 0;
        };
        using SharedPublisherPlugin = std::shared_ptr< PublisherPluginApi >;
    } // namespace plugins
} // namespace pub_sub

#endif // LIBCDS_PUBSUB_PUB_PLUGIN_HH
