/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2020  The Symbiflow Authors
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
#include <algorithm>
#include "clocks.h"
#include "kernel/log.h"
#include "kernel/register.h"
#include "kernel/rtlil.h"
#include "propagation.h"
#include "sdc_writer.h"
#include "set_clock_groups.h"
#include "set_false_path.h"
#include "set_max_delay.h"

USING_YOSYS_NAMESPACE

PRIVATE_NAMESPACE_BEGIN

struct ReadSdcCmd : public Frontend {
    ReadSdcCmd() : Frontend("sdc", "Read SDC file") {}

    void help() override {
	log("\n");
	log("    read_sdc <filename>\n");
	log("\n");
	log("Read SDC file.\n");
	log("\n");
    }

    void execute(std::istream*& f, std::string filename,
                 std::vector<std::string> args, RTLIL::Design*) override {
	if (args.size() < 2) {
	    log_cmd_error("Missing script file.\n");
	}
	log("\nReading clock constraints file(SDC)\n\n");
	size_t argidx = 1;
	extra_args(f, filename, args, argidx);
	std::string content{std::istreambuf_iterator<char>(*f),
	                    std::istreambuf_iterator<char>()};
	log("%s\n", content.c_str());
	Tcl_Interp* interp = yosys_get_tcl_interp();
	if (Tcl_EvalFile(interp, args[argidx].c_str()) != TCL_OK) {
	    log_cmd_error("TCL interpreter returned an error: %s\n",
	                  Tcl_GetStringResult(interp));
	}
    }
};

struct WriteSdcCmd : public Backend {
    WriteSdcCmd(SdcWriter& sdc_writer)
        : Backend("sdc", "Write SDC file"), sdc_writer_(sdc_writer) {}

    void help() override {
	log("\n");
	log("    write_sdc <filename>\n");
	log("\n");
	log("Write SDC file.\n");
	log("\n");
    }

    void execute(std::ostream*& f, std::string filename,
                 std::vector<std::string> args,
                 RTLIL::Design* design) override {
	if (args.size() < 2) {
	    log_cmd_error("Missing output file.\n");
	}
	log("\nWriting out clock constraints file(SDC)\n");
	extra_args(f, filename, args, 1);
	sdc_writer_.WriteSdc(design, *f);
    }

    SdcWriter& sdc_writer_;
};

struct CreateClockCmd : public Pass {
    CreateClockCmd() : Pass("create_clock", "Create clock object") {}

    void help() override {
	log("\n");
	log("    create_clock [ -name clock_name ] -period period_value "
	    "[-waveform <edge_list>] <target>\n");
	log("Define a clock.\n");
	log("If name is not specified then the name of the first target is "
	    "selected as the clock's name.\n");
	log("Period is expressed in nanoseconds.\n");
	log("The waveform option specifies the duty cycle (the rising a "
	    "falling edges) of the clock.\n");
	log("It is specified as a list of two elements/time values: the first "
	    "rising edge and the next falling edge.\n");
	log("\n");
    }

    void execute(std::vector<std::string> args,
                 RTLIL::Design* design) override {
	size_t argidx;
	std::string name;
	bool is_waveform_specified(false);
	float rising_edge(0);
	float falling_edge(0);
	float period(0);
	if (args.size() < 4) {
	    log_cmd_error("Incorrect number of arguments\n");
	}
	for (argidx = 1; argidx < args.size(); argidx++) {
	    std::string arg = args[argidx];
	    if (arg == "-name" && argidx + 1 < args.size()) {
		name = args[++argidx];
		continue;
	    }
	    if (arg == "-period" && argidx + 1 < args.size()) {
		period = std::stof(args[++argidx]);
		continue;
	    }
	    if (arg == "-waveform" && argidx + 1 < args.size()) {
		std::string edges(args[++argidx]);
		std::copy_if(edges.begin(), edges.end(), edges.begin(),
		             [](char c) { return c != '{' or c != '}'; });
		std::stringstream ss(edges);
		ss >> rising_edge >> falling_edge;
		is_waveform_specified = true;
		continue;
	    }
	    break;
	}
	if (period <= 0) {
	    log_cmd_error("Incorrect period value\n");
	}
	// Add "w:" prefix to selection arguments to enforce wire object
	// selection
	AddWirePrefix(args, argidx);
	extra_args(args, argidx, design);
	// If clock name is not specified then take the name of the first target
	std::vector<RTLIL::Wire*> selected_wires;
	for (auto module : design->modules()) {
	    if (!design->selected(module)) {
		continue;
	    }
	    for (auto wire : module->wires()) {
		if (design->selected(module, wire)) {
#ifdef SDC_DEBUG
		    log("Selected wire %s\n",
		        RTLIL::unescape_id(wire->name).c_str());
#endif
		    selected_wires.push_back(wire);
		}
	    }
	}
	if (selected_wires.size() == 0) {
	    log_cmd_error("Target selection is empty\n");
	}
	if (name.empty()) {
	    name = RTLIL::unescape_id(selected_wires.at(0)->name);
	}
	if (!is_waveform_specified) {
	    rising_edge = 0;
	    falling_edge = period / 2;
	}
	Clock::Add(name, selected_wires, period, rising_edge, falling_edge);
    }

    void AddWirePrefix(std::vector<std::string>& args, size_t argidx) {
	auto selection_begin = args.begin() + argidx;
	std::transform(selection_begin, args.end(), selection_begin,
	               [](std::string& w) { return "w:" + w; });
    }
};

struct GetClocksCmd : public Pass {
    GetClocksCmd() : Pass("get_clocks", "Create clock object") {}

    void help() override {
	log("\n");
	log("    get_clocks [-include_generated_clocks] [-of <nets>] "
	    "[<patterns>]\n");
	log("\n");
	log("Returns all clocks in the design.\n");
	log("\n");
	log("    -include_generated_clocks\n");
	log("        Include auto-generated clocks.\n");
	log("\n");
	log("    -of\n");
	log("        Get clocks of these nets.\n");
	log("\n");
	log("    <pattern>\n");
	log("        Pattern of clock names. Default are all clocks in the "
	    "design.\n");
	log("\n");
    }

    std::vector<std::string> extract_list(const std::string& args) {
	std::vector<std::string> port_list;
	std::stringstream ss(args);
	std::istream_iterator<std::string> begin(ss);
	std::istream_iterator<std::string> end;
	std::copy(begin, end, std::back_inserter(port_list));
	return port_list;
    }

    // TODO Check for GENERATED_CLOCK clock wire attribute
    // Issue https://github.com/SymbiFlow/yosys-symbiflow-plugins/issues/53
    // For now don't treat any of the added clocks as auto-generated
    bool IsGeneratedClock(RTLIL::Wire* clock_wire) {
	(void)clock_wire;
	return false;
    }

    void execute(std::vector<std::string> args,
                 RTLIL::Design* design) override {

	// Parse command arguments
	bool generated_clocks(false);
	std::vector<std::string> clocks_nets;
	size_t argidx(0);

	// Parse command switches
	for (argidx = 1; argidx < args.size(); argidx++) {
	    std::string arg = args[argidx];
	    if (arg == "-include_generated_clocks") {
		generated_clocks = true;
		continue;
	    }
	    if (arg == "-of" and argidx + 1 < args.size()) {
		clocks_nets = extract_list(args[++argidx]);
#ifdef SDC_DEBUG
		for (auto clock_net : clocks_nets) {
		    log("Clock filter %s\n", clock_net.c_str());
		}
#endif
		continue;
	    }
	    if (arg.size() > 0 and arg[0] == '-') {
		log_cmd_error("Unknown option %s.\n", arg.c_str());
	    }

	    break;
	}

	// Parse object patterns
	std::vector<std::string> clocks_list(args.begin() + argidx, args.end());

	// Fetch clocks in the design
	std::map<std::string, RTLIL::Wire*> clocks(Clocks::GetClocks(design));
	if (clocks.size() == 0) {
	    log_warning("No clocks found in design\n");
	}

	// Extract clocks into tcl list
	Tcl_Interp* interp = yosys_get_tcl_interp();
	Tcl_Obj* tcl_list = Tcl_NewListObj(0, NULL);
	for (auto& clock : clocks) {
	    // Skip generated clocks if -include_generated_clocks is not specified
	    if (IsGeneratedClock(clock.second) and !generated_clocks) {
		continue;
	    }
	    // Check if clock name is in the list of design clocks
	    if (clocks_list.size() > 0 and
	        std::find(clocks_list.begin(), clocks_list.end(),
	                  clock.first) == clocks_list.end()) {
		continue;
	    }
	    // Check if clock wire is in the -of list
	    if (clocks_nets.size() > 0 and
	        std::find(clocks_nets.begin(), clocks_nets.end(),
	                  Clock::WireName(clock.second)) == clocks_nets.end()) {
		continue;
	    }
	    auto& wire = clock.second;
	    const char* name = RTLIL::id2cstr(wire->name);
	    Tcl_Obj* name_obj = Tcl_NewStringObj(name, -1);
	    Tcl_ListObjAppendElement(interp, tcl_list, name_obj);
	}
	Tcl_SetObjResult(interp, tcl_list);
    }
};

struct PropagateClocksCmd : public Pass {
    PropagateClocksCmd()
        : Pass("propagate_clocks", "Propagate clock information") {}

    void help() override {
	log("\n");
	log("    propagate_clocks\n");
	log("\n");
	log("Propagate clock information throughout the design.\n");
	log("\n");
    }

    void execute(std::vector<std::string> args,
                 RTLIL::Design* design) override {
	if (args.size() > 1) {
	    log_warning(
	        "Command accepts no arguments.\nAll will be ignored.\n");
	}
	if (!design->top_module()) {
	    log_cmd_error("No top module selected\n");
	}

	std::array<std::unique_ptr<Propagation>, 2> passes{
	    std::unique_ptr<Propagation>(new BufferPropagation(design, this)),
	    std::unique_ptr<Propagation>(
	        new ClockDividerPropagation(design, this))};

	log("Perform clock propagation\n");

	for (auto& pass : passes) {
	    pass->Run();
	}
    }
};

class SdcPlugin {
   public:
    SdcPlugin()
        : write_sdc_cmd_(sdc_writer_),
          set_false_path_cmd_(sdc_writer_),
          set_max_delay_cmd_(sdc_writer_),
          set_clock_groups_cmd_(sdc_writer_) {
	log("Loaded SDC plugin\n");
    }

    ReadSdcCmd read_sdc_cmd_;
    WriteSdcCmd write_sdc_cmd_;
    CreateClockCmd create_clock_cmd_;
    GetClocksCmd get_clocks_cmd_;
    PropagateClocksCmd propagate_clocks_cmd_;
    SetFalsePath set_false_path_cmd_;
    SetMaxDelay set_max_delay_cmd_;
    SetClockGroups set_clock_groups_cmd_;

   private:
    SdcWriter sdc_writer_;
} SdcPlugin;

PRIVATE_NAMESPACE_END
