#pragma once

#include <util/generic/maybe.h>
#include <util/generic/singleton.h>
#include <util/stream/file.h>
#include <util/string/join.h>

#include <library/cpp/on_disk/aho_corasick/reader.h>
#include <library/cpp/on_disk/aho_corasick/writer.h>
#include <library/cpp/regex/pcre/regexp.h>

namespace NWebmaster {

struct TSearchEngine {
    TSearchEngine() = default;
    TSearchEngine(const NJson::TJsonValue &json);

public:
    int Id;
    TString SearchEngine;
    TMaybe<int> ParentId;
    int weight;
    TString URL;
    TMaybe<int> form_num;
    TString field_name;
    bool Hide;
    TString CheckType;
    TMaybe<TString> PageParameterPattern;
    TMaybe<TString> PageParameterOffset;
    TMaybe<TString> PageParameterDivisor;
    TString StrId;
    TMaybe<TString> Domain;
};

struct TSearchEnginePattern {
    TSearchEnginePattern() = default;
    TSearchEnginePattern(const NJson::TJsonValue &json);

    bool Match(const TString &str) const;

public:
    int Id;
    int SearchEngineId;
    TString Pattern;
    TString QuickPattern;
    TString Charset;
    TRegExMatch Regex;
};

struct TSearchEngines {
    using TAhoSearcher = TMappedAhoCorasick<TString, ui32>;

    TSearchEngines();

    void LoadSearchEngines();
    void LoadSearchEnginesPatterns();
    bool Match(const TString &str, THashSet<int> &matchedSEIds) const;
    const TSearchEngine &Get(int id) const;

    static const TSearchEngines &CInstance() {
        return *Singleton<TSearchEngines>();
    }

public:
    THashMap<int, TSearchEngine> SearchEngines;
    THashMap<int, TSearchEnginePattern> SearchEnginesPatterns;
    THashMap<TString, TDeque<int>> QuickPatternsMap;
    TDeque<std::pair<TString, TDeque<int>>> QuickPatternsList;
    THolder<TAhoSearcher> AhoSearcher;
};

} //namespace NWebmaster
