#include "client.h"
#include <saas/api/action.h>
#include <saas/api/indexing_client/client.h>

#include <search/session/compression/compression.h>

#include <library/cpp/logger/global/global.h>
#include <util/string/vector.h>

namespace NSaas {

    void TSaasIndexerMap::Start(ui32 /*jobId*/, ui64 /*recordStart*/, NMR::TUpdate& /*output*/) {
        DoInitGlobalLog("console", Options.LogLevel, false, false);
        RowProcessor.Reset(IRowProcessor::TFactory::Construct(Options.Processor, Options.ProcessorOptions));
        VERIFY_WITH_LOG(RowProcessor.Get(), "Unknown row processor");
        Indexer = MakeHolder<TMultithreadIndexer>(Options);
    }

    void TSaasIndexerMap::Finish(ui32 /*jobId*/, NMR::TUpdate& /*output*/) {
        Indexer.Destroy();
    }

    void TSaasIndexerMap::DoSub(NMR::TValue key, NMR::TValue subkey, NMR::TValue value, NMR::TUpdate &output) {
        TAtomicSharedPtr<TAction> action;
        try {
            action = MakeAtomicShared<TAction>(RowProcessor->ProcessRowSingle(key, subkey, value));
        } catch (const yexception& e) {
            FAIL_LOG("Error at row '%s': %s", key.AsString().data(), e.what());
        }

        const TString& keyString = key.AsString();
        Indexer->IndexDocument(action, [this, keyString, &output](const NSaas::TSendResult& result, const NSaas::TAction&) {
            if (result.GetCode() != TSendResult::srOK) {
                NMR::TValue httpCode(ToString(result.GetHttpCode()) + "\t" + result.GetMessage());
                TGuard<TMutex> guard(UpdateMutex);
                output.Add(keyString, httpCode);
            }
        });
    }

    void TSaasYTMapper::Start(TWriter* /*writer*/) {
        Indexer = MakeHolder<TMultithreadIndexer>(Options);
        RowProcessor.Reset(IRowProcessor::TFactory::Construct(Options.Processor, Options.ProcessorOptions));
    }

    void TSaasYTMapper::Finish(TWriter* /*writer*/) {
        Indexer.Destroy();
    }

    void TSaasYTMapper::Do(TReader* input, TWriter* /*output*/) {
        for (; input->IsValid(); input->Next()) {
            TAtomicSharedPtr<TAction> action;
            try {
                action = MakeAtomicShared<TAction>(RowProcessor->ProcessRowSingle(input->GetRow()));
            } catch (const yexception& e) {
                FAIL_LOG("Error in RowProcessor: %s", e.what());
            }
            Indexer->IndexDocument(action, [](const NSaas::TSendResult&, const NSaas::TAction&){});
        }

    }
}

REGISTER_SAVELOAD_NM_CLASS(0x12345679, NSaas, TSaasIndexerMap)
REGISTER_MAPPER(NSaas::TSaasYTMapper)
