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

#include "NFA.h"

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 {
                    ASSERT(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:
            ABORT("unreachable");
        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;
}

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) + ">";
    }
}
