#include "document_parser.h"

#include <saas/rtyserver/config/common_indexers_config.h>
#include <saas/rtyserver/config/config.h>

void TComponentParser::Parse(TParsingContext& /*context*/) const {
}

// TDocumentParser
void TDocumentParser::Parse(TParsedDocument& result, const NRTYServer::TMessage::TDocument& document, NRTYServer::TMessage::TMessageType command, const NRTYServer::TDocParseContext& docParseContext) const {
    Clear(result);

    if (!document.GetUrl())
        throw yexception() << "Document url was not set";
    result.SetDocSearchInfo(TDocSearchInfo(document.GetUrl(), document.GetKeyPrefix()));
    SetRealtime(result, document.GetRealtime());
    SetVersion(result, document.GetVersion());
    SetStreamId(result, document.GetStreamId());
    SetTimestamp(result, document.GetModificationTimestamp());
    SetVersionTimestamp(result, document.HasVersionTimestamp() ? document.GetVersionTimestamp() : document.GetModificationTimestamp());
    SetUpdateType(result, document.GetUpdateType());

    if (document.HasPosition()) {
        SetPosition(result, document.GetPosition());
    }

    for (auto&& position : document.GetExtraPositions()) {
        AddExtraPosition(result, position);
    }

    for (auto&& timestamp : document.GetTimestamps()) {
        const NRTYServer::TTimestampValue value = { timestamp.GetValueEx(), timestamp.GetValue() };
        AddExtraTimestamp(result, timestamp.GetStream(), value);
    }

    if (command == NRTYServer::TMessage::DEPRECATED__UPDATE_DOCUMENT) {
        result.SignalIsUpdate();
    }

    for (auto& i: Parsers) {
        TComponentParser::TParsingContext ctx(result, document, command, docParseContext);
        i.second->Parse(ctx);
    }

    if (!result.GetConfig().GetCommonIndexers().UseSlowUpdate && result.IsNeedRestore()) {
        ythrow yexception() << "Detected document with need restore flag, but UseSlowUpdate == false in current configuration";
    }

    if (result.GetIsUpdate() && result.GetUpdateType() == NRTYServer::TMessage::FAST && result.IsNeedRestore()) {
        throw yexception() << "Update declared as fast but requires restoring";
    }
}

void TDocumentParser::CreateAndRegisterParser(const NRTYServer::IIndexComponent& component) {
    NRTYServer::IComponentParser::TPtr parser = component.BuildParser();
    if (!!parser)
        Parsers[component.GetName()] = parser;
}
