#include "histogram.h"
#include "shard_conf.h"
#include "static_data.h"

#include <saas/rtyserver/components/oxy/fresh_mixer/fresh_mixer.h>
#include <saas/rtyserver/components/oxy/hash_sorter/processor.h>
#include <saas/rtyserver/components/oxy/panther/processor.h>

#include <robot/library/oxygen/indexer/processor/bundle/interface.h>

namespace {
    class TRTYServerProcessorsBundle : public NOxygen::IProcessorsBundle {
    public:
        void CreateDocumentProcessors(TVector<NOxygen::TProcessorPtr>& processors, const NOxygen::TOxygenOptions& options, const NOxygen::TCreateProcessorsContext& context) const override {
            if (options.HasShardConfOptions()) {
                processors.push_back(new NOxygen::TShardConfProcessor(options.GetShardConfOptions(), context.OutputDirectory));
            }
            if (options.HasStaticDataOptions()) {
                processors.push_back(new NOxygen::TStaticDataProcessor(options.GetStaticDataOptions(), context.OutputDirectory));
            }

            const NOxygen::TRTYProcessorOptions& rtyserverOptions = options.GetRTYProcessorOptions();
            if (rtyserverOptions.HasHistogramOptions()) {
                NRTYServer::THistogramProcessor::TEntities entities;

                const auto& histogramOptions = rtyserverOptions.GetHistogramOptions();
                for (size_t i = 0; i < histogramOptions.SourceSize(); ++i) {
                    const auto& source = histogramOptions.GetSource(i);
                    NRTYServer::THistogramProcessor::TEntity entity;
                    entity.TupleName = source.GetTupleName();
                    entity.Period = source.GetRange();
                    entities.push_back(entity);
                }

                processors.push_back(new NRTYServer::THistogramProcessor(entities, context.OutputDirectory));
            }
            if (rtyserverOptions.HasPantherOptions()) {
                processors.push_back(new NRTYServer::TPantherProcessor(context.OutputDirectory, context.OutputDirectory, rtyserverOptions.GetPantherOptions(), context.TaskPool));
            }
        }

        void CreateHostProcessors(TVector<NOxygen::TProcessorPtr>& processors, const NOxygen::TOxygenOptions& options, const NOxygen::TCreateProcessorsContext& context) const override {
            Y_UNUSED(processors);
            Y_UNUSED(options);
            Y_UNUSED(context);
        }

        NOxygen::IPruningProcessorPtr CreatePruningProcessor(NOxygen::TProcessorPtr slave, const NOxygen::TOxygenOptions& options, const NOxygen::TCreateProcessorsContext& context) const override {
            const auto& rtyOptions = options.GetRTYProcessorOptions();
            if (rtyOptions.HasMixerOptions()) {
                const NOxygen::TRTYMixerOptions& mixerOptions = rtyOptions.GetMixerOptions();
                return new TFreshMixer(
                    context.TaskPool,
                    slave,
                    mixerOptions,
                    context.OutputDirectory / "index",
                    true
                );
            }
            if (rtyOptions.HasHashSorterOptions()) {
                return new THashSorterProcessor(
                    context.TaskPool,
                    slave,
                    rtyOptions.GetHashSorterOptions().GetUrlTupleName(),
                    context.OutputDirectory / "index"
                );
            }
            return nullptr;
        }
    };
}

NOxygen::TBundleFactory::TRegistrator<TRTYServerProcessorsBundle> RTYServerProcessorsBundle("RTYServer");
