#include "invhash_normalizer.h"

#include <saas/rtyserver/components/generator/manager.h>
#include <saas/rtyserver/config/config.h>
#include <saas/rtyserver/config/searcher_config.h>

#include <ysite/yandex/erf/inv_url_hashes.h>

TInvHashNormalizer::TInvHashNormalizer(const TRTYServerConfig& config)
    : NRTYServer::INormalizer(config)
{
}

const char* TInvHashNormalizer::Name() const {
    return "InvHash";
}

bool TInvHashNormalizer::AllRight(const NRTYServer::TNormalizerContext& context, const THolder<TFileMap>& /*indexFrq*/) const {
    if (!context.Config.GetSearcherConfig().EnableUrlHash) {
        return true;
    }

    const TString& filename = context.Dir.PathName() + "/" + "indexinvhash";
    if (!NFs::Exists(filename)) {
        ERROR_LOG << "InvHash file " << filename << " is missing" << Endl;
        return false;
    }

    if (const IUrlIdInfo* info = context.Index->GetUrlIdInfo()) {
        TInvUrlHashes reader(filename);
        for (ui32 docId = 0; docId < context.Managers.GetDocumentsCount(); ++docId) {
            ui32 invHashDocId;
            if (!reader.GetDocId(info->GetUrlId(docId), &invHashDocId)) {
                ERROR_LOG << "Can not get InvHash DocId for DocId " << docId << Endl;
                return false;
            }
            if (docId != invHashDocId) {
                ERROR_LOG << "InvHash DocId " << invHashDocId << " differs from real DocId " << docId << Endl;
                return false;
            }
        }
    }

    return true;
}

void TInvHashNormalizer::Fix(const NRTYServer::TNormalizerContext& context, const THolder<TFileMap>& /*indexFrq*/) const {
    const IUrlIdInfo* info = context.Index->GetUrlIdInfo();
    AssertCorrectIndex(info, "UrlIdInfo is missing");

    const TFsPath root = context.Dir.PathName();
    const TFsPath file = root / "indexinvhash";
    const TFsPath temp = root / "~indexinvhash";

    TInvUrlHashesWriter iuh;
    for (ui32 i = 0; i < context.Managers.GetDocumentsCount(); ++i) {
        iuh.Add(info->GetUrlId(i), i);
    }
    iuh.Write(temp);
    temp.RenameTo(file);
}
