/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/sksl/lex/NFAtoDFA.h"
#include "src/sksl/lex/RegexParser.h"

#include <fstream>
#include <sstream>
#include <string>

/**
 * Processes a .lex file and produces .h and .cpp files which implement a lexical analyzer. The .lex
 * file is a text file with one token definition per line. Each line is of the form:
 * <TOKEN_NAME> = <pattern>
 * where <pattern> is either a regular expression (e.g [0-9]) or a double-quoted literal string.
 */

static constexpr const char* HEADER =
    "/*\n"
    " * Copyright 2017 Google Inc.\n"
    " *\n"
    " * Use of this source code is governed by a BSD-style license that can be\n"
    " * found in the LICENSE file.\n"
    " */\n"
    "/*****************************************************************************************\n"
    " ******************** This file was generated by sksllex. Do not edit. *******************\n"
    " *****************************************************************************************/\n";

void writeH(const DFA& dfa, const char* lexer, const char* token,
            const std::vector<std::string>& tokens, const char* hPath) {
    std::ofstream out(hPath);
    SkASSERT(out.good());
    out << HEADER;
    out << "#ifndef SKSL_" << lexer << "\n";
    out << "#define SKSL_" << lexer << "\n";
    out << "#include <cstddef>\n";
    out << "#include <cstdint>\n";
    out << "namespace SkSL {\n";
    out << "\n";
    out << "struct " << token << " {\n";
    out << "    enum class Kind {\n";
    for (const std::string& t : tokens) {
        out << "        TK_" << t << ",\n";
    }
    out << "        TK_NONE,";
    out << R"(
    };

    )" << token << R"(()
    : fKind(Kind::TK_NONE)
    , fOffset(-1)
    , fLength(-1) {}

    )" << token << R"((Kind kind, int32_t offset, int32_t length)
    : fKind(kind)
    , fOffset(offset)
    , fLength(length) {}

    Kind fKind;
    int fOffset;
    int fLength;
};

class )" << lexer << R"( {
public:
    void start(const char* text, int32_t length) {
        fText = text;
        fLength = length;
        fOffset = 0;
    }

    )" << token << R"( next();

    int32_t getCheckpoint() const {
        return fOffset;
    }

    void rewindToCheckpoint(int32_t checkpoint) {
        fOffset = checkpoint;
    }

private:
    const char* fText;
    int32_t fLength;
    int32_t fOffset;
};

} // namespace
#endif
)";
}

void writeCPP(const DFA& dfa, const char* lexer, const char* token, const char* include,
              const char* cppPath) {
    std::ofstream out(cppPath);
    SkASSERT(out.good());
    out << HEADER;
    out << "#include \"" << include << "\"\n";
    out << "\n";
    out << "namespace SkSL {\n";
    out << "\n";

    size_t states = 0;
    for (const auto& row : dfa.fTransitions) {
        states = std::max(states, row.size());
    }
    out << "using State = " << (states <= 256 ? "uint8_t" : "int16_t") << ";\n";
    // arbitrarily-chosen character which is greater than START_CHAR and should not appear in actual
    // input
    out << "static const uint8_t INVALID_CHAR = 18;";
    out << "static int8_t mappings[" << dfa.fCharMappings.size() << "] = {\n    ";
    const char* separator = "";
    for (int m : dfa.fCharMappings) {
        out << separator << std::to_string(m);
        separator = ", ";
    }
    out << "\n};\n";
    out << "static State transitions[" << dfa.fTransitions.size() << "][" << states << "] = {\n";
    for (size_t c = 0; c < dfa.fTransitions.size(); ++c) {
        out << "    {";
        for (size_t j = 0; j < states; ++j) {
            if ((size_t) c < dfa.fTransitions.size() && j < dfa.fTransitions[c].size()) {
                out << " " << dfa.fTransitions[c][j] << ",";
            } else {
                out << " 0,";
            }
        }
        out << " },\n";
    }
    out << "};\n";
    out << "\n";

    out << "static int8_t accepts[" << states << "] = {";
    for (size_t i = 0; i < states; ++i) {
        if (i < dfa.fAccepts.size()) {
            out << " " << dfa.fAccepts[i] << ",";
        } else {
            out << " " << INVALID << ",";
        }
    }
    out << " };\n";
    out << "\n";

    out << token << " " << lexer << "::next() {";
    out << R"(
    // note that we cheat here: normally a lexer needs to worry about the case
    // where a token has a prefix which is not itself a valid token - for instance,
    // maybe we have a valid token 'while', but 'w', 'wh', etc. are not valid
    // tokens. Our grammar doesn't have this property, so we can simplify the logic
    // a bit.
    int32_t startOffset = fOffset;
    if (startOffset == fLength) {
        return )" << token << "(" << token << R"(::Kind::TK_END_OF_FILE, startOffset, 0);
    }
    State state = 1;
    for (;;) {
        if (fOffset >= fLength) {
            if (accepts[state] == -1) {
                return Token(Token::Kind::TK_END_OF_FILE, startOffset, 0);
            }
            break;
        }
        uint8_t c = (uint8_t) fText[fOffset];
        if (c <= 8 || c >= )" << dfa.fCharMappings.size() << R"() {
            c = INVALID_CHAR;
        }
        State newState = transitions[mappings[c]][state];
        if (!newState) {
            break;
        }
        state = newState;
        ++fOffset;
    }
    Token::Kind kind = ()" << token << R"(::Kind) accepts[state];
    return )" << token << R"((kind, startOffset, fOffset - startOffset);
}

} // namespace
)";
}

void process(const char* inPath, const char* lexer, const char* token, const char* hPath,
             const char* cppPath) {
    NFA nfa;
    std::vector<std::string> tokens;
    tokens.push_back("END_OF_FILE");
    std::string line;
    std::ifstream in(inPath);
    while (std::getline(in, line)) {
        if (line.length() == 0) {
            continue;
        }
        if (line.length() >= 2 && line[0] == '/' && line[1] == '/') {
            continue;
        }
        std::istringstream split(line);
        std::string name, delimiter, pattern;
        if (split >> name >> delimiter >> pattern) {
            SkASSERT(split.eof());
            SkASSERT(name != "");
            SkASSERT(delimiter == "=");
            SkASSERT(pattern != "");
            tokens.push_back(name);
            if (pattern[0] == '"') {
                SkASSERT(pattern.size() > 2 && pattern[pattern.size() - 1] == '"');
                RegexNode node = RegexNode(RegexNode::kChar_Kind, pattern[1]);
                for (size_t i = 2; i < pattern.size() - 1; ++i) {
                    node = RegexNode(RegexNode::kConcat_Kind, node,
                                     RegexNode(RegexNode::kChar_Kind, pattern[i]));
                }
                nfa.addRegex(node);
            }
            else {
                nfa.addRegex(RegexParser().parse(pattern));
            }
        }
    }
    NFAtoDFA converter(&nfa);
    DFA dfa = converter.convert();
    writeH(dfa, lexer, token, tokens, hPath);
    writeCPP(dfa, lexer, token, (std::string("src/sksl/SkSL") + lexer + ".h").c_str(), cppPath);
}

int main(int argc, const char** argv) {
    if (argc != 6) {
        printf("usage: sksllex <input.lex> <lexername> <tokenname> <output.h> <output.cpp>\n");
        exit(1);
    }
    process(argv[1], argv[2], argv[3], argv[4], argv[5]);
    return 0;
}
