/*
 * 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/RegexNode.h"

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

#include <string>

std::vector<int> RegexNode::createStates(NFA* nfa, const std::vector<int>& accept) const {
    std::vector<int> result;
    switch (fKind) {
        case kChar_Kind:
            result.push_back(nfa->addState(NFAState(fPayload.fChar, accept)));
            break;
        case kCharset_Kind: {
            std::vector<bool> chars;
            for (const RegexNode& child : fChildren) {
                if (child.fKind == kChar_Kind) {
                    while (chars.size() <= (size_t) child.fPayload.fChar) {
                        chars.push_back(false);
                    }
                    chars[child.fPayload.fChar] = true;
                } else {
                    SkASSERT(child.fKind == kRange_Kind);
                    while (chars.size() <= (size_t) child.fChildren[1].fPayload.fChar) {
                        chars.push_back(false);
                    }
                    for (char c = child.fChildren[0].fPayload.fChar;
                         c <= child.fChildren[1].fPayload.fChar;
                         ++c) {
                        chars[c] = true;
                    }
                }
            }
            result.push_back(nfa->addState(NFAState(fPayload.fBool, chars, accept)));
            break;
        }
        case kConcat_Kind: {
            std::vector<int> right = fChildren[1].createStates(nfa, accept);
            result = fChildren[0].createStates(nfa, right);
            break;
        }
        case kDot_Kind:
            result.push_back(nfa->addState(NFAState(NFAState::kDot_Kind, accept)));
            break;
        case kOr_Kind: {
            std::vector<int> states = fChildren[0].createStates(nfa, accept);
            result.insert(result.end(), states.begin(), states.end());
            states = fChildren[1].createStates(nfa, accept);
            result.insert(result.end(), states.begin(), states.end());
            break;
        }
        case kPlus_Kind: {
            std::vector<int> next = accept;
            std::vector<int> placeholder;
            int id = nfa->addState(NFAState(placeholder));
            next.push_back(id);
            result = fChildren[0].createStates(nfa, next);
            nfa->fStates[id] = NFAState(result);
            break;
        }
        case kQuestion_Kind:
            result = fChildren[0].createStates(nfa, accept);
            result.insert(result.end(), accept.begin(), accept.end());
            break;
        case kRange_Kind:
            SkUNREACHABLE;
        case kStar_Kind: {
            std::vector<int> next = accept;
            std::vector<int> placeholder;
            int id = nfa->addState(NFAState(placeholder));
            next.push_back(id);
            result = fChildren[0].createStates(nfa, next);
            result.insert(result.end(), accept.begin(), accept.end());
            nfa->fStates[id] = NFAState(result);
            break;
        }
    }
    return result;
}

#ifdef SK_DEBUG
std::string RegexNode::description() const {
    switch (fKind) {
        case kChar_Kind:
            return std::string(1, fPayload.fChar);
        case kCharset_Kind: {
            std::string result("[");
            if (fPayload.fBool) {
                result += "^";
            }
            for (const RegexNode& c : fChildren) {
                result += c.description();
            }
            result += "]";
            return result;
        }
        case kConcat_Kind:
            return fChildren[0].description() + fChildren[1].description();
        case kDot_Kind:
            return ".";
        case kOr_Kind:
            return "(" + fChildren[0].description() + "|" + fChildren[1].description() + ")";
        case kPlus_Kind:
            return fChildren[0].description() + "+";
        case kQuestion_Kind:
            return fChildren[0].description() + "?";
        case kRange_Kind:
            return fChildren[0].description() + "-" + fChildren[1].description();
        case kStar_Kind:
            return fChildren[0].description() + "*";
        default:
            return "<" + std::to_string(fKind) + ">";
    }
}
#endif
