/* Connection string stage parsing helper
Copyright (C) 2026 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_STAGE_ADDRESS_HH
#define LIBCDS_PUBSUB_STAGE_ADDRESS_HH

#include <map>
#include <string>

/*!
 * @file stage_address.hh
 * @brief Structured parsing of a pipeline stage string.
 * @details A connection string is a '|' separated pipeline of stages.
 * Each stage has the form scheme://path and may carry options as URL
 * style query parameters, scheme://path?key1=value1&key2=value2.
 *
 * Plugins receive the raw stage string; parse_stage_address is the
 * helper the built-in transports use to split it apart, and is public
 * so that custom plugins can adopt the same convention.
 */
namespace pub_sub
{
    /*!
     * @brief A pipeline stage broken into its components.
     */
    struct StageAddress
    {
        /// The stage type, "tcp" for a "tcp://..." stage.
        std::string scheme{ };
        /// Everything after "://" with the query stripped.
        std::string path{ };
        /// The query parameters, empty if there was no query.
        std::map< std::string, std::string > arguments{ };
    };

    /*!
     * @brief Parse a pipeline stage of the form scheme://path?k1=v1&k2=v2
     * @details The query is everything after the first '?'; no '?' (or a
     * bare trailing '?') yields empty arguments.  Each query component is
     * key=value, split at the first '=' — values may contain '=' and '?'
     * and may be empty.  No URL-decoding is performed.
     * @param stage The stage string to parse.
     * @return The parsed stage.
     * @throws std::runtime_error if "://" is absent, the scheme is empty,
     * a query component is empty or has no '=' or an empty key, or a key
     * is duplicated.
     */
    StageAddress parse_stage_address( const std::string& stage );
} // namespace pub_sub

#endif // LIBCDS_PUBSUB_STAGE_ADDRESS_HH
