/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2019  David Shah <dave@ds0.me>
 *
 *  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 "nextpnr.h"
#include "util.h"

NEXTPNR_NAMESPACE_BEGIN

namespace SDF {

struct MinMaxTyp
{
    double min, typ, max;
};

struct RiseFallDelay
{
    MinMaxTyp rise, fall;
};

struct PortAndEdge
{
    std::string port;
    ClockEdge edge;
};

struct IOPath
{
    std::string from, to;
    RiseFallDelay delay;
};

struct TimingCheck
{
    enum CheckType
    {
        SETUPHOLD,
        PERIOD,
        WIDTH
    } type;
    PortAndEdge from, to;
    RiseFallDelay delay;
};

struct Cell
{
    std::string celltype, instance;
    std::vector<IOPath> iopaths;
    std::vector<TimingCheck> checks;
};

struct CellPort
{
    std::string cell, port;
};

struct Interconnect
{
    CellPort from, to;
    RiseFallDelay delay;
};

struct SDFWriter
{
    bool cvc_mode = false;
    std::vector<Cell> cells;
    std::vector<Interconnect> conn;
    std::string sdfversion, design, vendor, program;

    std::string format_name(const std::string &name)
    {
        std::string fmt = "\"";
        for (char c : name) {
            if (c == '\\' || c == '\"')
                fmt += "\"";
            fmt += c;
        }
        fmt += "\"";
        return fmt;
    }

    std::string escape_name(const std::string &name)
    {
        std::string esc;
        for (char c : name) {
            if (c == '$' || c == '\\' || c == '[' || c == ']' || c == ':' || (cvc_mode && c == '.'))
                esc += '\\';
            esc += c;
        }
        return esc;
    }

    std::string timing_check_name(TimingCheck::CheckType type)
    {
        switch (type) {
        case TimingCheck::SETUPHOLD:
            return "SETUPHOLD";
        case TimingCheck::PERIOD:
            return "PERIOD";
        case TimingCheck::WIDTH:
            return "WIDTH";
        default:
            NPNR_ASSERT_FALSE("unknown timing check type");
        }
    }

    void write_delay(std::ostream &out, const RiseFallDelay &delay)
    {
        write_delay(out, delay.rise);
        out << " ";
        write_delay(out, delay.fall);
    }

    void write_delay(std::ostream &out, const MinMaxTyp &delay)
    {
        if (cvc_mode)
            out << "(" << int(delay.min) << ":" << int(delay.typ) << ":" << int(delay.max) << ")";
        else
            out << "(" << delay.min << ":" << delay.typ << ":" << delay.max << ")";
    }

    void write_port(std::ostream &out, const CellPort &port)
    {
        if (cvc_mode)
            out << escape_name(port.cell) + "." + escape_name(port.port);
        else
            out << escape_name(port.cell + "/" + port.port);
    }

    void write_portedge(std::ostream &out, const PortAndEdge &pe)
    {
        out << "(" << (pe.edge == RISING_EDGE ? "posedge" : "negedge") << " " << escape_name(pe.port) << ")";
    }

    void write(std::ostream &out)
    {
        out << "(DELAYFILE" << std::endl;
        // Headers and  metadata
        out << "  (SDFVERSION " << format_name(sdfversion) << ")" << std::endl;
        out << "  (DESIGN " << format_name(design) << ")" << std::endl;
        out << "  (VENDOR " << format_name(vendor) << ")" << std::endl;
        out << "  (PROGRAM " << format_name(program) << ")" << std::endl;
        out << "  (DIVIDER " << (cvc_mode ? "." : "/") << ")" << std::endl;
        out << "  (TIMESCALE 1ps)" << std::endl;
        // Write interconnect delays, with the main design begin a "cell"
        out << "  (CELL" << std::endl;
        out << "    (CELLTYPE " << format_name(design) << ")" << std::endl;
        out << "    (INSTANCE )" << std::endl;
        out << "    (DELAY" << std::endl;
        out << "      (ABSOLUTE" << std::endl;
        for (auto &ic : conn) {
            out << "        (INTERCONNECT ";
            write_port(out, ic.from);
            out << " ";
            write_port(out, ic.to);
            out << " ";
            write_delay(out, ic.delay);
            out << ")" << std::endl;
        }
        out << "      )" << std::endl;
        out << "    )" << std::endl;
        out << "  )" << std::endl;
        // Write cells
        for (auto &cell : cells) {
            out << "  (CELL" << std::endl;
            out << "    (CELLTYPE " << format_name(cell.celltype) << ")" << std::endl;
            out << "    (INSTANCE " << escape_name(cell.instance) << ")" << std::endl;
            // IOPATHs (combinational delay and clock-to-q)
            if (!cell.iopaths.empty()) {
                out << "    (DELAY" << std::endl;
                out << "      (ABSOLUTE" << std::endl;
                for (auto &path : cell.iopaths) {
                    out << "        (IOPATH " << escape_name(path.from) << " " << escape_name(path.to) << " ";
                    write_delay(out, path.delay);
                    out << ")" << std::endl;
                }
                out << "      )" << std::endl;
                out << "    )" << std::endl;
            }
            // Timing Checks (setup/hold, period, width)
            if (!cell.checks.empty()) {
                out << "    (TIMINGCHECK" << std::endl;
                for (auto &check : cell.checks) {
                    out << "      (" << timing_check_name(check.type) << " ";
                    write_portedge(out, check.from);
                    out << " ";
                    if (check.type == TimingCheck::SETUPHOLD) {
                        write_portedge(out, check.to);
                        out << " ";
                    }
                    if (check.type == TimingCheck::SETUPHOLD)
                        write_delay(out, check.delay);
                    else
                        write_delay(out, check.delay.rise);
                    out << ")" << std::endl;
                }
                out << "    )" << std::endl;
            }
            out << "    )" << std::endl;
        }
        out << ")" << std::endl;
    }
};

} // namespace SDF

void Context::writeSDF(std::ostream &out, bool cvc_mode) const
{
    using namespace SDF;
    SDFWriter wr;
    wr.cvc_mode = cvc_mode;
    wr.design = str_or_default(attrs, id("module"), "top");
    wr.sdfversion = "3.0";
    wr.vendor = "nextpnr";
    wr.program = "nextpnr";

    const double delay_scale = 1000;
    // Convert from DelayInfo to SDF-friendly RiseFallDelay
    auto convert_delay = [&](const DelayInfo &dly) {
        RiseFallDelay rf;
        rf.rise.min = getDelayNS(dly.minRaiseDelay()) * delay_scale;
        rf.rise.typ = getDelayNS((dly.minRaiseDelay() + dly.maxRaiseDelay()) / 2) * delay_scale; // fixme: typ delays?
        rf.rise.max = getDelayNS(dly.maxRaiseDelay()) * delay_scale;
        rf.fall.min = getDelayNS(dly.minFallDelay()) * delay_scale;
        rf.fall.typ = getDelayNS((dly.minFallDelay() + dly.maxFallDelay()) / 2) * delay_scale; // fixme: typ delays?
        rf.fall.max = getDelayNS(dly.maxFallDelay()) * delay_scale;
        return rf;
    };

    auto convert_setuphold = [&](const DelayInfo &setup, const DelayInfo &hold) {
        RiseFallDelay rf;
        rf.rise.min = getDelayNS(setup.minDelay()) * delay_scale;
        rf.rise.typ = getDelayNS((setup.minDelay() + setup.maxDelay()) / 2) * delay_scale; // fixme: typ delays?
        rf.rise.max = getDelayNS(setup.maxDelay()) * delay_scale;
        rf.fall.min = getDelayNS(hold.minDelay()) * delay_scale;
        rf.fall.typ = getDelayNS((hold.minDelay() + hold.maxDelay()) / 2) * delay_scale; // fixme: typ delays?
        rf.fall.max = getDelayNS(hold.maxDelay()) * delay_scale;
        return rf;
    };

    for (auto cell : sorted(cells)) {
        Cell sc;
        const CellInfo *ci = cell.second;
        sc.instance = ci->name.str(this);
        sc.celltype = ci->type.str(this);
        for (auto port : ci->ports) {
            int clockCount = 0;
            TimingPortClass cls = getPortTimingClass(ci, port.first, clockCount);
            if (cls == TMG_IGNORE)
                continue;
            if (port.second.net == nullptr)
                continue; // Ignore disconnected ports
            if (port.second.type != PORT_IN) {
                // Add combinational paths to this output (or inout)
                for (auto other : ci->ports) {
                    if (other.second.net == nullptr)
                        continue;
                    if (other.second.type == PORT_OUT)
                        continue;
                    DelayInfo dly;
                    if (!getCellDelay(ci, other.first, port.first, dly))
                        continue;
                    IOPath iop;
                    iop.from = other.first.str(this);
                    iop.to = port.first.str(this);
                    iop.delay = convert_delay(dly);
                    sc.iopaths.push_back(iop);
                }
                // Add clock-to-output delays, also as IOPaths
                if (cls == TMG_REGISTER_OUTPUT)
                    for (int i = 0; i < clockCount; i++) {
                        auto clkInfo = getPortClockingInfo(ci, port.first, i);
                        IOPath cqp;
                        cqp.from = clkInfo.clock_port.str(this);
                        cqp.to = port.first.str(this);
                        cqp.delay = convert_delay(clkInfo.clockToQ);
                        sc.iopaths.push_back(cqp);
                    }
            }
            if (port.second.type != PORT_OUT && cls == TMG_REGISTER_INPUT) {
                // Add setup/hold checks
                for (int i = 0; i < clockCount; i++) {
                    auto clkInfo = getPortClockingInfo(ci, port.first, i);
                    TimingCheck chk;
                    chk.from.edge = RISING_EDGE; // Add setup/hold checks equally for rising and falling edges
                    chk.from.port = port.first.str(this);
                    chk.to.edge = clkInfo.edge;
                    chk.to.port = clkInfo.clock_port.str(this);
                    chk.type = TimingCheck::SETUPHOLD;
                    chk.delay = convert_setuphold(clkInfo.setup, clkInfo.hold);
                    sc.checks.push_back(chk);
                    chk.from.edge = FALLING_EDGE;
                    sc.checks.push_back(chk);
                }
            }
        }
        wr.cells.push_back(sc);
    }

    for (auto net : sorted(nets)) {
        NetInfo *ni = net.second;
        if (ni->driver.cell == nullptr)
            continue;
        for (auto &usr : ni->users) {
            Interconnect ic;
            ic.from.cell = ni->driver.cell->name.str(this);
            ic.from.port = ni->driver.port.str(this);
            ic.to.cell = usr.cell->name.str(this);
            ic.to.port = usr.port.str(this);
            // FIXME: min/max routing delay - or at least constructing DelayInfo here
            ic.delay = convert_delay(getDelayFromNS(getDelayNS(getNetinfoRouteDelay(ni, usr))));
            wr.conn.push_back(ic);
        }
    }
    wr.write(out);
}

NEXTPNR_NAMESPACE_END