#include <sstream>
#include "read_xml_util.h"

#include "vtr_util.h"
#include "arch_error.h"

using namespace pugiutil;

/* Convert bool to ReqOpt enum */ 
extern ReqOpt BoolToReqOpt(bool b) {
	if (b) {
		return REQUIRED;	
	}
	return OPTIONAL;
}

InstPort::InstPort(std::string str) {
    std::vector<std::string> inst_port = vtr::split(str, ".");

    if(inst_port.size() == 1) {
        instance_ = {"", -1, -1};
        port_ = parse_name_index(inst_port[0]);

    } else if(inst_port.size() == 2) {
        instance_ = parse_name_index(inst_port[0]);
        port_ = parse_name_index(inst_port[1]);
    } else {
        std::string msg = vtr::string_fmt("Failed to parse instance port specification '%s'",
                                str.c_str());
        throw ArchFpgaError(msg);
    }
}

InstPort::InstPort(std::string str, pugi::xml_node node, const pugiutil::loc_data& loc_data) {
    try {
        *this = InstPort(str);
    } catch (const ArchFpgaError& e) {
		archfpga_throw(loc_data.filename_c_str(), loc_data.line(node),
				"Failed to parse instance port specification '%s' for"
                " on <%s> tag, %s",
				str.c_str(), node.name(), e.what());
    }
}

InstPort::InstPort(pugi::xml_attribute attr, pugi::xml_node node, const pugiutil::loc_data& loc_data) {
    try {
        *this = InstPort(attr.value());
    } catch (const ArchFpgaError& e) {
		archfpga_throw(loc_data.filename_c_str(), loc_data.line(node),
				"Failed to parse instance port specification '%s' for"
                " attribute '%s' on <%s> tag, %s",
				attr.value(), attr.name(), node.name(), e.what());
    }
}

InstPort::name_index InstPort::parse_name_index(std::string str) {
    auto open_bracket_pos = str.find("["); 
    auto close_bracket_pos = str.find("]"); 
    auto colon_pos = str.find(":"); 

    //Parse checks
    if(open_bracket_pos == std::string::npos && close_bracket_pos != std::string::npos) {
        //Close brace only
        std::string msg = "near '" + str + "', missing '['";
        throw ArchFpgaError(msg);
    }

    if(open_bracket_pos != std::string::npos && close_bracket_pos == std::string::npos) {
        //Open brace only
        std::string msg = "near '" + str + "', missing ']'";
        throw ArchFpgaError(msg);
    }

    if(open_bracket_pos != std::string::npos && close_bracket_pos != std::string::npos) {
        //Have open and close braces, close must be after open
        if(open_bracket_pos > close_bracket_pos) {
            std::string msg = "near '" + str + "', '[' after ']'";
            throw ArchFpgaError(msg);
        }
    }

    if(colon_pos != std::string::npos) {
        //Have a colon, it must be between open/close braces
        if(colon_pos > close_bracket_pos || colon_pos < open_bracket_pos) {
            std::string msg = "near '" + str + "', found ':' but not between '[' and ']'";
            throw ArchFpgaError(msg);
        }
    }


    //Extract the name and index info
    std::string name = str.substr(0,open_bracket_pos);
    std::string first_idx_str;
    std::string second_idx_str;

    if(colon_pos == std::string::npos && open_bracket_pos == std::string::npos && close_bracket_pos == std::string::npos) {
    } else if(colon_pos == std::string::npos) {
        //No colon, implies a single element
        first_idx_str = str.substr(open_bracket_pos + 1, close_bracket_pos);
        second_idx_str = first_idx_str;
    } else {
        //Colon, implies a range
        first_idx_str = str.substr(open_bracket_pos + 1, colon_pos);
        second_idx_str = str.substr(colon_pos + 1, close_bracket_pos);
    }

    int first_idx = UNSPECIFIED;
    if(!first_idx_str.empty()) {
        std::stringstream ss(first_idx_str);
        size_t idx;
        ss >> idx;
        if(!ss.good()) {
            std::string msg = "near '" + str + "', expected positive integer";
            throw ArchFpgaError(msg);
        }
        first_idx = idx;
    }

    int second_idx = UNSPECIFIED;
    if(!second_idx_str.empty()) {
        std::stringstream ss(second_idx_str);
        size_t idx;
        ss >> idx;
        if(!ss.good()) {
            std::string msg = "near '" + str + "', expected positive integer";
            throw ArchFpgaError(msg);
        }
        second_idx = idx;
    }

    return {name, std::min(first_idx, second_idx), std::max(first_idx, second_idx)};

}


void bad_tag(const pugi::xml_node node,
                const pugiutil::loc_data& loc_data,
                const pugi::xml_node parent_node,
                const std::vector<std::string> expected_tags) {

    std::string msg = "Unexpected tag ";
    msg += "<";
    msg += node.name();
    msg += ">";

    if(parent_node) {
        msg += " in section <";
        msg += parent_node.name();
        msg += ">";
    }

    if(!expected_tags.empty()) {
        msg += ", expected ";
        for(auto iter = expected_tags.begin(); iter != expected_tags.end(); ++iter) {
            msg += "<";
            msg += *iter;
            msg += ">"; 

            if(iter < expected_tags.end() - 2) {
                msg += ", ";
            } else if(iter == expected_tags.end() - 2) {
                msg += " or ";
            }
        }
    }

    throw ArchFpgaError(msg, loc_data.filename(), loc_data.line(node));
}

void bad_attribute(const pugi::xml_attribute attr,
                const pugi::xml_node node,
                const pugiutil::loc_data& loc_data,
                const std::vector<std::string> expected_attributes) {

    std::string msg = "Unexpected attribute ";
    msg += "'";
    msg += attr.name();
    msg += "'";

    if(node) {
        msg += " on <";
        msg += node.name();
        msg += "> tag";
    }

    if(!expected_attributes.empty()) {
        msg += ", expected ";
        for(auto iter = expected_attributes.begin(); iter != expected_attributes.end(); ++iter) {
            msg += "'";
            msg += *iter;
            msg += "'"; 

            if(iter < expected_attributes.end() - 2) {
                msg += ", ";
            } else if(iter == expected_attributes.end() - 2) {
                msg += " or ";
            }
        }
    }

    throw ArchFpgaError(msg, loc_data.filename(), loc_data.line(node));
}

void bad_attribute_value(const pugi::xml_attribute attr,
                const pugi::xml_node node,
                const pugiutil::loc_data& loc_data,
                const std::vector<std::string> expected_values) {

    std::string msg = "Invalid value '";
    msg += attr.value();
    msg += "'";
    msg += " for attribute '";
    msg += attr.name();
    msg += "'";

    if(node) {
        msg += " on <";
        msg += node.name();
        msg += "> tag";
    }

    if(!expected_values.empty()) {
        msg += ", expected value ";
        for(auto iter = expected_values.begin(); iter != expected_values.end(); ++iter) {
            msg += "'";
            msg += *iter;
            msg += "'"; 

            if(iter < expected_values.end() - 2) {
                msg += ", ";
            } else if(iter == expected_values.end() - 2) {
                msg += " or ";
            }
        }
    }

    throw ArchFpgaError(msg, loc_data.filename(), loc_data.line(node));
}
