#ifndef INCLUDED_FILTER_
#define INCLUDED_FILTER_

#include <iosfwd>
#include <vector>
#include <unordered_map>
#include <unordered_set>

#include "../enums/enums.h"
#include "../current/current.h"
#include "../expr/expr.h"
#include "../rule/rule.h"
#include "../rules/rules.h"
#include "../condition/condition.h"

class Filter
{
    eAction d_action;                // by default: accept
    Current d_current;
    Condition d_condition;

    using FileRulesMap = std::unordered_map<std::string, Rules>;
    FileRulesMap d_map;

    std::string d_filename;             // currently processed Rules file

    using StringSet = std::unordered_set<std::string>;
    StringSet d_matchedFiles;       // filenames having matched Rule(s)

                                    // ptrs to access the currently active
    Rules *d_rules;                 // Rules, updated at each Rule file
    Rule *d_rule;
    Expr *d_expr;

    public:
        Filter();   // does nothing (as default)

                                                // R+ handled by Rules
                                                // R  handled by Rule

        bool accept(eAction action);             // F matched: perform 'action'

                                    // R start a Rule, 1st offset is known
        void addRule(size_t begin, size_t rule,                         // .f
                     std::string const &nrTxt, size_t beyondIdx);

        void matchMode(eMatchMode mode);         // E receives the mode    .f
        
        void endRule(size_t end);                                       // .f

                                                // handles the received mail:
        void done();                            // maybe default mail handling

                                                // calls condition/matched
        bool matchCondition();                  // C may alter d_condition  .f

                                                // R test the current expr
        void matchExpr(eTruth truth);           // update the Rule's status .f

        bool matchRule();                       // R+ true: a Rule matched

                                                // true: sensible regex     .f
        bool regex(std::string const &txt);     // E clean up a received regex

                                    // F a new file or use the available one
                                    //   it sets the offset of the 1st Rule
                                    //   object to 0.
        void rulesFile(std::string const &filename);    

                                                // R set the rule's date info
        void setDate(std::string const &date, size_t idx);              // .f

                                                    // F set header in Mail
        void setHeader(std::string const &header);  // and d_current

                                                // lineNr: of the Rules file
        void startIf(size_t lineNr);            // F start a new if-stmnt
};

#include "filter.f"

#endif
