#include "block_mode.h"

bool TBlockModeRearrange::DoFormCgiParameters(TCgiParameters& cgi) {
    auto itText = cgi.equal_range("text");
    TBlockHash blockHash(BlockCount);
    auto itKps = cgi.find("sgkps");
    TString kps = "0";
    if (itKps != cgi.end()) {
        kps = itKps->second;
    }
    cgi.EraseAll("gta");
    cgi.EraseAll("sgkps");
    for (auto it = itText.first; it != itText.second; ++it) {
        cgi.InsertUnescaped("gta", blockHash.GetGtaKey(kps, it->second));
        it->second = ToString(blockHash.GetBlockKey(kps, it->second));
    }
    return true;
}

void TBlockModeRearrange::DoProcessReplies(TVector<NProxyMeta::TSourceReply>& replies, ICustomReportBuilder& /*builder*/, IReplyContext& /*context*/) const {
    for (auto& answerSource : replies) {
        NMetaProtocol::TReport& answer = *answerSource.Report;

        if (answer.GroupingSize() == 0) {
            continue;
        }

        TSet<TString> repeatedGtaKey;
        for (ui32 gr = 0; gr < answer.GetGrouping(0).GroupSize(); ++gr) {
            NMetaProtocol::TGroup& blockGroup = *answer.MutableGrouping(0)->MutableGroup(gr);
            NMetaProtocol::TGroup group;

            for (ui32 doc = 0; doc < blockGroup.DocumentSize(); ++doc) {
                NMetaProtocol::TArchiveInfo& blockArchiveInfo = *blockGroup.MutableDocument(doc)->MutableArchiveInfo();

                ui32 sizeGta = blockArchiveInfo.GtaRelatedAttributeSize();
                if (sizeGta == 0) {
                    continue;
                }

                NMetaProtocol::TDocument* document = group.AddDocument();
                document->SetDocId(blockGroup.MutableDocument(doc)->GetDocId());

                for (const auto& attr : blockArchiveInfo.GetGtaRelatedAttribute()) {
                    if (repeatedGtaKey.contains(attr.GetKey())) {
                        continue;
                    } else {
                        if (sizeGta != 1) {
                            repeatedGtaKey.insert(attr.GetKey());
                        }
                        NRTYServer::TMessage::TDocument blockDocument;
                        Y_PROTOBUF_SUPPRESS_NODISCARD blockDocument.ParseFromString(attr.GetValue());
                        FillDocument(document, blockDocument);
                        break;
                    }
                }

            }

            blockGroup.Swap(&group);
        }
    }

}

void TBlockModeRearrange::FillDocument(NMetaProtocol::TDocument* newDoc, NRTYServer::TMessage::TDocument& doc) const {
    NMetaProtocol::TArchiveInfo* archiveInfo = newDoc->MutableArchiveInfo();
    newDoc->SetUrl(doc.GetUrl());

    archiveInfo->SetTitle(doc.GetUrl());
    if (doc.HasBody()) {
        auto passage = archiveInfo->AddPassage();
        *passage = doc.GetBody();
    }
    for (const auto& it : doc.GetDocumentProperties()) {
        auto attr = archiveInfo->AddGtaRelatedAttribute();
        attr->SetValue(it.GetValue());
        attr->SetKey(it.GetName());
    }
}
