#pragma once
#ifndef LEXESIS_BACKENDS_CPP_H
#define LEXESIS_BACKENDS_CPP_H

#include "Lexesis/backend.h"

namespace lxs
{
namespace backends
{
    /**
     * A backend that emits c++ code
     */
    class CppBackend : public Backend {
        public:
            CppBackend();
            virtual ~CppBackend();

            virtual std::string getName();
            virtual bool canProcessLang(std::string lang);

            virtual void generateLexer(std::function<std::unique_ptr<std::ostream>(std::string)> getOstreamForFileName, std::string lexerName, const DFA& dfa);

        private:
            /**
             * Build a TemplateContext that represents the transition table
             *
             * @param transition_idx \see buildTransitionIndices
             */
            templ::TemplateContext buildTable(const DFA& dfa, const std::vector<unsigned char>& transition_idx, int num_transitions_per_state) const;

            /**
             * Build a TemplateContext that represents the list of associated tokens with each state
             */
            templ::TemplateContext buildTokenList(const DFA& dfa) const;

            /**
             * For compression of the table, build a list that maps each char to an index
             * This way, whenever multiple chars always represent the same transition, the can get the same index, and the table is smaller
             *
             * @return a pair with the list and the number of distinct indices
             */
            std::pair<std::vector<unsigned char>, int> buildTransitionIndices(const DFA& dfa) const;

            /**
             * Transform the given indices (\see buildTransitionIndices) to a usable TemplateContext
             */
            templ::TemplateContext transformTransitionIndices(const std::vector<unsigned char>& transition_indices) const;
    };

}
}

#endif //LEXESIS_BACKENDS_CPP_H
