//
// Created by jonathan.hanks on 2/1/21.
//

#include "pipeline_parser.hh"
//#include <cctype>
//#include <sstream>

#include <boost/algorithm/string.hpp>
//#include <boost/optional.hpp>

namespace
{
    //    template <typename It>
    //    std::tuple<boost::optional<std::string>, It>
    //    parse_pipeline_stage(It start, It end) {
    //        boost::optional<std::string> results;
    //        std::ostringstream os;
    //
    //        if (start == end)
    //        {
    //            return std::make_tuple(results, start);
    //        }
    //
    //        bool first = true;
    //        auto cur = start;
    //        for (; cur != end && *cur != '|'; ++cur)
    //        {
    //            auto ch = *cur;
    //            if (first)
    //            {
    //                if (!std::isalnum(ch))
    //                {
    //                    return std::make_tuple(results, start);
    //                }
    //                first = false;
    //            }
    //            os << ch;
    //        }
    //        auto stage = os.str();
    //        if (stage.empty())
    //        {
    //            return std::make_tuple(results, start);
    //        }
    //        results = os.str();
    //        return std::make_tuple(results, cur);
    //    }
    //
    //
    //    template <typename It>
    //    std::tuple<bool, It>
    //    parse_pipeline_seperator(It start, It end)
    //    {
    //        if (start != end)
    //        {
    //            if (*start == '|')
    //            {
    //                return std::make_tuple(true, start+1);
    //            }
    //        }
    //        return std::make_tuple(false, start);
    //    }
    //
    //    template <typename It>
    //    std::tuple<boost::optional<std::vector<std::string> >, It>
    //    parse_pipeline_list(It start, It end)
    //    {
    //        std::vector<std::string> pipelines;
    //        auto errors =
    //        std::make_tuple(boost::optional<std::vector<std::string>>(),
    //        start);
    //
    //        boost::optional<std::string> pipeline;
    //        It cur = start;
    //        It next = cur;
    //
    //        std::tie(pipeline, next) = parse_pipeline_stage(start, end);
    //        if (pipeline)
    //        {
    //            pipelines.emplace_back(pipeline.get());
    //        }
    //        else
    //        {
    //            return errors;
    //        }
    //        cur = next;
    //
    //        while (true)
    //        {
    //            auto have_sep = false;
    //            std::tie(have_sep, next) = parse_pipeline_seperator(cur, end);
    //            if (!have_sep)
    //            {
    //                return
    //                std::make_tuple(boost::optional<std::vector<std::string>>(pipelines),
    //                end);
    //            }
    //            cur = next;
    //
    //            std::tie(pipeline, next) = parse_pipeline_stage(cur, end);
    //            if (pipeline)
    //            {
    //                pipelines.template emplace_back(pipeline.get());
    //            }
    //            else
    //            {
    //                return errors;
    //            }
    //            cur = next;
    //        }
    //
    //    }
    //
    //    std::vector<std::string>
    //    do_parse_pipeline_list(const std::string& input)
    //    {
    //        boost::optional<std::vector<std::string> > pipelines;
    //        auto next = input.begin();
    //        std::tie(pipelines, next) = parse_pipeline_list(input.begin(),
    //        input.end());
    //
    //        if (!pipelines || next != input.end()) {
    //            return std::vector<std::string>{};
    //        }
    //        return pipelines.get();
    //    }

    std::vector< std::string >
    do_parse_pipeline_list( const std::string& input )
    {
        std::vector< std::string > pipelines;

        boost::split( pipelines, input, boost::is_any_of( "|" ) );
        for ( const auto& entry : pipelines )
        {
            if ( entry.empty( ) )
            {
                pipelines.clear( );
                break;
            }
        }
        return pipelines;
    }

} // namespace

namespace pub_sub
{
    namespace detail
    {
        std::vector< std::string >
        parse_pipeline( const std::string& input )
        {
            std::vector< std::string > pipelines;
            pipelines = do_parse_pipeline_list( input );
            return pipelines;
        }
    } // namespace detail
} // namespace pub_sub