/*
 *  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 <array>

#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 [-include_propagated_clocks] <filename>\n");
        log("\n");
        log("Write SDC file.\n");
        log("\n");
        log("    -include_propagated_clocks\n");
        log("       Write out all propagated clocks");
        log("\n");
    }

    void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
    {
        size_t argidx;
        bool include_propagated = false;
        if (args.size() < 2) {
            log_cmd_error("Missing output file.\n");
        }
        for (argidx = 1; argidx < args.size(); argidx++) {
            std::string arg = args[argidx];
            if (arg == "-include_propagated_clocks" && argidx + 1 < args.size()) {
                include_propagated = true;
                continue;
            }
            break;
        }
        log("\nWriting out clock constraints file(SDC)\n");
        extra_args(f, filename, args, argidx);
        sdc_writer_.WriteSdc(design, *f, include_propagated);
    }

    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, Clock::EXPLICIT);
    }

    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;
    }

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

        // Parse command arguments
        bool include_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") {
                include_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 propagated clocks (i.e. clock wires with the same parameters
            // as the master clocks they originate from
            if (Clock::IsPropagated(clock.second)) {
                continue;
            }
            // Skip generated clocks if -include_generated_clocks is not specified
            if (Clock::IsGenerated(clock.second) and !include_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();
        }

        Clocks::UpdateAbc9DelayTarget(design);
    }
};

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
