
#include "import_mentor.hpp"
#include "system/pins.hpp"
#include "system/parts.hpp"

#include <vector>
#include <string>
#include <regex>

using namespace std;

enum class State
{
    NO_PART,
    IS_PART,
};

ImportMentor::ImportMentor(string filename) : ImportBase(filename) {}

ImportMentor::~ImportMentor()
{
    ImportBase::~ImportBase();
}

void ImportMentor::parse()
{
    string line;
    auto state = State::NO_PART;
    const regex name_regex("'([^'\\s][^']*)'");
    const regex part_regex("^COMP:");
    const regex pin_regex("^\\s*Explicit Pin:");

    bool is_name_match = false;
    bool is_part_match = false;
    bool is_pin_match = false;
    Part *prt = nullptr;
    while (getline(file_lines, line))
    {
        vector<string> names;
        for (sregex_iterator it(line.begin(), line.end(), name_regex), end; it != end; ++it)
        {
            names.push_back((*it)[1]);
        }
        is_name_match = (names.size() > 0);
        is_part_match = regex_search(line, part_regex);
        is_pin_match = regex_search(line, pin_regex);
        switch (state)
        {
        case State::NO_PART:
            if (is_part_match)
            {
                if (is_name_match)
                {
                    prt = new Part(names[1]);
                    state = State::IS_PART;
                }
            }
            break;

        default:
            if (is_part_match)
            {
                if (is_name_match)
                {
                    prts->add(prt);
                    prt = new Part(names[1]);
                }
            }
            else if (is_pin_match)
            {
                if (is_name_match)
                {
                    auto pin = new Pin(names[0]);
                    Signal *s = nullptr;
                    prt->add(pin);
                    if (!sigs->exists(names[2]))
                    {
                        s = new Signal(names[2]);
                        sigs->add(s);
                    } else {
                        s = sigs->get(names[2]);
                    };
                    pin->connect(s);
                }
            }
            break;
        }
    }
    if (state == State::IS_PART)
    {
        prts->add(prt);
    }
}