#include "regexp_docid_filter.h"

#include <kernel/tarc/markup_zones/text_markup.h>
#include <kernel/tarc/markup_zones/arcreader.h>

TRegExpDocidsFilter::TRegExpDocidsFilter(const IArchiveData& archiveData)
        : ArchiveData(archiveData)
{}

void TRegExpDocidsFilter::AddFilter(const TString& regExp, const TString& propName, bool inverseMatching, bool ignoreCase) {
    Regexps.push_back(new TRegexpConfigs(regExp, propName, inverseMatching, ignoreCase));
}

bool TRegExpDocidsFilter::Empty() const {
    return Regexps.size() == 0;
}

bool TRegExpDocidsFilter::DocumentBanned(ui32 docId) const {
    if (!ArchiveData.IsInArchive(docId)) {
        return true;
    }

    TBlob extInfo = ArchiveData.GetDocExtInfo(docId)->UncompressBlob();

    TDocDescr descr;
    descr.UseBlob(extInfo.Data(), (unsigned int)extInfo.Size());

    THashMap<TString, TString> docInfos;
    descr.ConfigureDocInfos(docInfos);

    for (const auto& regexp : Regexps){
        if (!regexp->Check(docInfos.at(regexp->PropName))){
            return true;
        }
    }
    return false;
}

TRegExpDocidsFilter::TRegexpConfigs::TRegexpConfigs(const TString& regexp, const TString& propName, bool inverseMatching, bool ignoreCase)
    : RegExp(regexp, RE2OptionsWithIgnoreCase(ignoreCase))
    , PropName(propName)
    , InverseMatching(inverseMatching)
{}

bool TRegExpDocidsFilter::TRegexpConfigs::Check(const TString& text) const {
    return RE2::PartialMatch(text, RegExp) ^ InverseMatching;
}

RE2::Options TRegExpDocidsFilter::TRegexpConfigs::RE2OptionsWithIgnoreCase(bool ignoreCase) {
    RE2::Options options;
    options.set_case_sensitive(!ignoreCase);
    return options;
}
