#include "Lexesis/driver.h"
#include "Lexesis/inputparser.h"

#include <iostream>
#include <fstream>

namespace {
    /**
     * Filter only valid identifier chars: alphanumeric, and not starting with a digit
     */
    std::string clean(std::string in) {
        std::string s;
        for (char c : in) {
            if ((s.length() && std::isalnum(c)) || std::isalpha(c) || c == '_')
                s += c;
        }
        return s;
    }
}

namespace lxs {
    Driver::Driver(std::unique_ptr<BackendManager> backends, std::istream& inputfile, std::string outputdir, std::string language, std::string lexername) :
                m_backends(std::move(backends)),
                m_inputfile(inputfile),
                m_outputdir(outputdir),
                m_language(language),
                m_lexername(clean(lexername))
    {}

    Driver::~Driver()
    {}

    int Driver::run() {
        if (!m_lexername.length()) {
            std::cerr << "No valid lexer name possible" << std::endl;
            return 1;
        }

        Backend* back = m_backends->findBackendForLang(m_language);
        if (!back) {
            std::cerr << "Could not find a valid backend for language " << m_language << std::endl;
            return 1;
        }

        DFA dfa = InputParser::parseInput(m_inputfile);

        back->generateLexer([this](std::string filename) -> std::unique_ptr<std::ostream> {
                    return std::unique_ptr<std::ostream>(new std::ofstream(m_outputdir + "/" + filename));
                },
                m_lexername, dfa);

        return 0;
    }
}
