#include "get_cmd.h"

USING_YOSYS_NAMESPACE

void GetCmd::help() {
    //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
    log("\n");
    log("   get_%ss [-quiet] [-filter filter_expression] "
        "<%s_selection> \n",
        TypeName().c_str(), TypeName().c_str());
    log("\n");
    log("Get matching %ss\n", TypeName().c_str());
    log("\n");
    log("Print the output to stdout too. This is useful when all Yosys "
        "is "
        "executed.\n");
    log("\n");
    log("    -filter\n");
    log("        Name and value of attribute to be taken into "
        "account.\n");
    log("        e.g. -filter { attr == \"true\" }\n");
    log("\n");
    log("    -quiet\n");
    log("        Don't print the result of the execution to stdout.\n");
    log("\n");
    log("    <selection_pattern>\n");
    log("        Selection of %s names. Default are all %ss in the "
        "design.\n",
        TypeName().c_str(), TypeName().c_str());
    log("\n");
}

void GetCmd::ExecuteSelection(RTLIL::Design* design, std::vector<std::string>& raw_args, const CommandArgs& args) {
    std::vector<std::string> selection_args;
    // Add name of top module to selection string
    std::transform(raw_args.begin() + args.current_args_idx, raw_args.end(),
                   std::back_inserter(selection_args), [&](std::string& obj) {
	               return RTLIL::unescape_id(design->top_module()->name) + "/" +
	                      SelectionType() + ":" + obj;
                   });
    extra_args(selection_args, 0, design);
    if (design->selected_modules().empty()) {
	if (!args.is_quiet) {
	    log_warning("Specified %s not found in design\n", TypeName().c_str());
	}
    }
}

void GetCmd::PackSelectionToTcl(RTLIL::Design* design, const CommandArgs& args) {
    // Pack the selected nets into Tcl List
    Tcl_Obj* tcl_list = Tcl_NewListObj(0, NULL);
    for (auto module : design->selected_modules()) {
	ExtractSelection(tcl_list, module, args);
    }
    if (!args.is_quiet) {
	log("\n");
    }
    Tcl_SetObjResult(yosys_get_tcl_interp(), tcl_list);
}

GetCmd::CommandArgs GetCmd::ParseCommand(const std::vector<std::string>& args) {
    CommandArgs parsed_args{.current_args_idx = 0,
                            .filters = Filters(),
                            .is_quiet = false,
                            .selection_objects = SelectionObjects()};
    size_t argidx;
    for (argidx = 1; argidx < args.size(); argidx++) {
	std::string arg = args[argidx];
	if (arg == "-quiet") {
	    parsed_args.is_quiet = true;
	    continue;
	}

	if (arg == "-filter" and argidx + 1 < args.size()) {
	    std::string filter_arg = args[++argidx];

	    // Remove spaces
	    filter_arg.erase(
	        std::remove_if(filter_arg.begin(), filter_arg.end(), isspace),
	        filter_arg.end());

	    // Parse filters
	    std::regex filter_attr_regex("(\\w+\\s?==\\s?\\w+)([(||)(&&)]*)");
	    std::regex_token_iterator<std::string::iterator> regex_end;
	    std::regex_token_iterator<std::string::iterator> matches(
	        filter_arg.begin(), filter_arg.end(), filter_attr_regex, 1);
	    if (matches == regex_end) {
		log_warning(
		    "Currently -filter switch supports only a single "
		    "'equal(==)' condition expression, the rest will be "
		    "ignored\n");
	    }

	    while (matches != regex_end) {
		std::string filter(*matches++);
		auto separator = filter.find("==");
		if (separator == std::string::npos) {
		    log_cmd_error("Incorrect filter expression: %s\n",
		                  args[argidx].c_str());
		}
		parsed_args.filters.emplace_back(filter.substr(0, separator),
		                     filter.substr(separator + 2));
	    }
	    if (parsed_args.filters.size() > 1) {
		log_warning(
		    "Currently -filter switch supports only a single "
		    "'equal(==)' condition expression, the rest will be "
		    "ignored\n");
	    }
	    continue;
	}

	if (arg.size() > 0 and arg[0] == '-') {
	    log_cmd_error("Unknown option %s.\n", arg.c_str());
	}

	break;
    }
    std::copy(args.begin() + argidx, args.end(), std::back_inserter(parsed_args.selection_objects));
    parsed_args.current_args_idx = argidx;
    return parsed_args;
}

void GetCmd::execute(std::vector<std::string> args, RTLIL::Design* design) {
    if (design->top_module() == nullptr) {
	log_cmd_error("No top module detected\n");
    }

    CommandArgs parsed_args(ParseCommand(args));
    ExecuteSelection(design, args, parsed_args);
    PackSelectionToTcl(design, parsed_args);
}
