#pragma once

#include <iostream>
#include <util/generic/string.h>

// Flex expects the signature of yylex to be defined in the macro YY_DECL, and
// the C++ parser expects it to be declared. We can factor both as follows.

#ifndef YY_DECL

#define YY_DECL \
    int NCssSanit::TCSS2Lexer::Lex(YYSTYPE* yylval)
#endif

#ifndef __FLEX_LEXER_H
#define yyFlexLexer css2FlexLexer
#include <contrib/tools/flex-old/FlexLexer.h>
#undef yyFlexLexer
#endif

namespace NCssSanit {
#include "css2_y.h"

    /** Scanner is a derived class to add some extra function to the scanner
 * class. Flex itself creates a class named yyFlexLexer, which is renamed using
 * macros to CSSFlexLexer. However we change the context of the generated
 * yylex() function to be contained within the Scanner class. This is required
 * because the yylex() defined in CSSFlexLexer has no parameters. */
    class TCSS2Lexer: public css2FlexLexer {
        TString SkipQuotedString(char quote_char);
        TString ExtractUrl(const char* text);
        void StripQuotes(TString& str);
        int ReadExpression(TString& expression_text);
        IInputStream& Inps;
        int StartToken;
        TGc& Gc;

    public:
        /** Create a new scanner object. The streams arg_yyin and arg_yyout default
     * to cin and cout, but that assignment is only made when initializing in
     * yylex(). */
        TCSS2Lexer(IInputStream& inps, bool inline_css, TGc& gc);

        /** Required for virtual functions */
        ~TCSS2Lexer() override;

        int LexerInput(char* buf, int max_size) override;

        /** This is the main lexing function. It is generated by flex according to
     * the macro declaration YY_DECL above. The generated bison parser then
     * calls this virtual function to fetch new tokens. */
        virtual int Lex(YYSTYPE* yylval);

        /** Enable debug output (via arg_yyout) if compiled into the scanner. */
        void SetDebug(bool b);
    };
}
