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

#ifndef SKSL_NFASTATE
#define SKSL_NFASTATE

#include <string>
#include <vector>

#include "src/sksl/lex/LexUtil.h"

struct NFAState {
    enum Kind {
        // represents an accept state - if the NFA ends up in this state, we have successfully
        // matched the token indicated by fData[0]
        kAccept_Kind,
        // matches the single character fChar
        kChar_Kind,
        // the regex '.'; matches any char but '\n'
        kDot_Kind,
        // a state which serves as a placeholder for the states indicated in fData. When we
        // transition to this state, we instead transition to all of the fData states.
        kRemapped_Kind,
        // contains a list of true/false values in fData. fData[c] tells us whether we accept the
        // character c.
        kTable_Kind
    };

    NFAState(Kind kind, std::vector<int> next)
    : fKind(kind)
    , fNext(std::move(next)) {}

    NFAState(char c, std::vector<int> next)
    : fKind(kChar_Kind)
    , fChar(c)
    , fNext(std::move(next)) {}

    NFAState(std::vector<int> states)
    : fKind(kRemapped_Kind)
    , fData(std::move(states)) {}

    NFAState(bool inverse, std::vector<bool> accepts, std::vector<int> next)
    : fKind(kTable_Kind)
    , fInverse(inverse)
    , fNext(std::move(next)) {
        for (bool b : accepts) {
            fData.push_back(b);
        }
    }

    NFAState(int token)
    : fKind(kAccept_Kind) {
        fData.push_back(token);
    }

    bool accept(char c) const {
        switch (fKind) {
            case kAccept_Kind:
                return false;
            case kChar_Kind:
                return c == fChar;
            case kDot_Kind:
                return c != '\n';
            case kTable_Kind: {
                bool value;
                if ((size_t) c < fData.size()) {
                    value = fData[c];
                } else {
                    value = false;
                }
                return value != fInverse;
            }
            default:
                ABORT("unreachable");
        }
    }

#ifdef SK_DEBUG
    std::string description() const {
        switch (fKind) {
            case kAccept_Kind:
                return "Accept(" + std::to_string(fData[0]) + ")";
            case kChar_Kind: {
                std::string result = "Char('" + std::string(1, fChar) + "'";
                for (int v : fNext) {
                    result += ", ";
                    result += std::to_string(v);
                }
                result += ")";
                return result;
            }
            case kDot_Kind: {
                std::string result = "Dot(";
                const char* separator = "";
                for (int v : fNext) {
                    result += separator;
                    result += std::to_string(v);
                    separator = ", ";
                }
                result += ")";
                return result;
            }
            case kRemapped_Kind: {
                std::string result = "Remapped(";
                const char* separator = "";
                for (int v : fData) {
                    result += separator;
                    result += std::to_string(v);
                    separator = ", ";
                }
                result += ")";
                return result;
            }
            case kTable_Kind: {
                std::string result = std::string("Table(") + (fInverse ? "true" : "false") + ", [";
                const char* separator = "";
                for (int v : fData) {
                    result += separator;
                    result += v ? "true" : "false";
                    separator = ", ";
                }
                result += "]";
                for (int n : fNext) {
                    result += ", ";
                    result += std::to_string(n);
                }
                result += ")";
                return result;
            }
            default:
                ABORT("unreachable");
        }
    }
#endif

    Kind fKind;

    char fChar = 0;

    bool fInverse = false;

    std::vector<int> fData;

    // states we transition to upon a succesful match from this state
    std::vector<int> fNext;
};

#endif
