#pragma once

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

#include <library/cpp/html/face/onchunk.h>
#include <library/cpp/html/face/zoneconf.h>
#include <library/cpp/yconf/conf.h>

#include <util/generic/hash.h>
#include <util/generic/hash_set.h>
#include <util/string/vector.h>
#include <util/stream/str.h>

class TZoneExtractor : public IParserResult {
public:
    TZoneExtractor(IZoneAttrConf& zoneAttrConf, const TZoneExtractorConfig& config);

    virtual THtmlChunk* OnHtmlChunk(const THtmlChunk& chunk) override;

protected:
    struct TZoneDescr {
        TZoneDescr(const TZoneExtractorConfigItem& config);
        TVector<TString> Content;
        i32 Started;
        const TZoneExtractorConfigItem& Config;
    };

    typedef THashMap<TString, TZoneDescr> TZonesDescription;

    TZonesDescription ZonesDescr;
    THolder<IParsedDocProperties> DocProperties;
    IZoneAttrConf& ZoneAttrConf;

private:
    typedef THashSet<TZoneDescr*> TZoneDescrSet;
    typedef THashMap<int, TZoneDescrSet> TTagCloseWaiters;
    struct TTagInfo {
        TTagInfo()
            : Level(0)
        {}
        ui32 Level;
        TTagCloseWaiters CloseWaiters;
    };
    typedef THashMap<TString, TTagInfo> TTagsInfo;

    void OnMarkup(const THtmlChunk& evnt);
    void OnOpenTag(const THtmlChunk& evnt);
    void OnCloseTag(const THtmlChunk& evnt);
    void OnBeginZone(const THtmlChunk& evnt, const TZoneEntry& zoneEntry);
    void OnEndZone(const THtmlChunk& evnt, TZoneDescr* descr);
    void OnText(const THtmlChunk& evnt, bool tag);

    TTagsInfo TagsInfo;
};
