#include "catch.hpp"

#include "vpr_api.h"
#include "vtr_util.h"
#include "rr_metadata.h"
#include "fasm.h"
#include "arch_util.h"
#include "rr_graph_writer.h"
#include <sstream>
#include <fstream>

static constexpr const char kArchFile[] = "test_fasm_arch.xml";
static constexpr const char kRrGraphFile[] = "test_fasm_rrgraph.xml";

namespace {

using Catch::Matchers::Equals;

TEST_CASE("fasm_integration_test", "[fasm]") {
    {
        t_vpr_setup vpr_setup;
        t_arch arch;
        t_options options;
        const char *argv[] = {
            "test_vpr",
            kArchFile,
            "wire.eblif",
            "--route_chan_width",
            "100",
        };
        vpr_init(sizeof(argv)/sizeof(argv[0]), argv,
                &options, &vpr_setup, &arch);
        bool flow_succeeded = vpr_flow(vpr_setup, arch);
        REQUIRE(flow_succeeded == true);

        auto &device_ctx = g_vpr_ctx.mutable_device();
        for(size_t inode = 0; inode < device_ctx.rr_nodes.size(); ++inode) {
            for(t_edge_size iedge = 0; iedge < device_ctx.rr_nodes[inode].num_edges(); ++iedge) {
                auto sink_inode = device_ctx.rr_nodes[inode].edge_sink_node(iedge);
                auto switch_id = device_ctx.rr_nodes[inode].edge_switch(iedge);
                vpr::add_rr_edge_metadata(inode, sink_inode, switch_id,
                        "fasm_features", vtr::string_fmt("%d_%d_%zu",
                            inode, sink_inode, switch_id));
            }
        }

        write_rr_graph(kRrGraphFile, vpr_setup.Segments);
        vpr_free_all(arch, vpr_setup);
    }

    t_vpr_setup vpr_setup;
    t_arch arch;
    t_options options;
    const char *argv[] = {
        "test_vpr",
        kArchFile,
        "wire.eblif",
        "--route_chan_width",
        "100",
        "--read_rr_graph",
        kRrGraphFile,
    };

    vpr_init(sizeof(argv)/sizeof(argv[0]), argv,
              &options, &vpr_setup, &arch);

    vpr_setup.PackerOpts.doPacking    = STAGE_LOAD;
    vpr_setup.PlacerOpts.doPlacement  = STAGE_LOAD;
    vpr_setup.RouterOpts.doRouting    = STAGE_LOAD;
    vpr_setup.AnalysisOpts.doAnalysis = STAGE_SKIP;

    bool flow_succeeded = vpr_flow(vpr_setup, arch);
    REQUIRE(flow_succeeded == true);

    std::stringstream fasm_string;
    fasm::FasmWriterVisitor visitor(fasm_string);
    NetlistWalker nl_walker(visitor);
    nl_walker.walk();

    fasm_string.seekg(0);

    std::ofstream fasm_file("output.fasm", std::ios_base::out);
    while(fasm_string) {
        std::string line;
        std::getline(fasm_string, line);
        fasm_file << line << std::endl;
    }

    fasm_string.clear();
    fasm_string.seekg(0);

    std::set<std::tuple<int, int, short>> routing_edges;
    bool found_lut5 = false;
    bool found_lut6 = false;
    bool found_mux1 = false;
    bool found_mux2 = false;
    bool found_mux3 = false;
    while(fasm_string) {
        // Should see something like:
        // CLB.FLE0.N2_LUT5
        // CLB.FLE8.LUT5_1.LUT[31:0]=32'b00000000000000010000000000000000
        // CLB.FLE9.OUT_MUX.LUT
        // CLB.FLE9.DISABLE_FF
        // CLB.FLE9.LUT6[63:0]=64'b0000000000000000000000000000000100000000000000000000000000000000
        // 3634_3690_0
        std::string line;
        std::getline(fasm_string, line);

        if(line == "") {
            continue;
        }

        if(!found_mux1 && line.find(".OUT_MUX.LUT") != std::string::npos) {
            found_mux1 = true;
        }
        if(!found_mux2 && line.find(".DISABLE_FF") != std::string::npos) {
            found_mux2 = true;
        }
        if(!found_mux3 && line.find(".IN0") != std::string::npos) {
            found_mux3 = true;
        }

        if(line.find("CLB") != std::string::npos || line.find("FLE") != std::string::npos) {
            auto pos = line.find("LUT[");
            if(pos != std::string::npos) {
                CHECK_THAT(line.substr(pos), Equals(
                           "LUT[31:0]=32'b00000000000000010000000000000000"));
                found_lut5 = true;
            }

            pos = line.find("LUT6[");
            if(pos != std::string::npos) {
                CHECK_THAT(line.substr(pos), Equals("LUT6[63:0]=64'b0000000000000000000000000000000100000000000000000000000000000000"));
                found_lut6 = true;
            }
        } else {
            auto parts = vtr::split(line, "_");
            REQUIRE(parts.size() == 3);
            auto src_inode = vtr::atoi(parts[0]);
            auto sink_inode = vtr::atoi(parts[1]);
            auto switch_id = vtr::atoi(parts[2]);

            auto ret = routing_edges.insert(std::make_tuple(src_inode, sink_inode, switch_id));
            CHECK(ret.second == true);
        }
    }

    const auto & route_ctx = g_vpr_ctx.routing();
    for(const auto &trace : route_ctx.trace) {
        const t_trace *head = trace.head;
        while(head != nullptr) {
            const t_trace *next = head->next;

            if(next != nullptr) {
                const auto next_inode = next->index;
                auto iter = routing_edges.find(std::make_tuple(head->index, next_inode, head->iswitch));
                CHECK(iter != routing_edges.end());
            }

            head = next;
        }
    }

    CHECK(found_lut5);
    CHECK(found_lut6);
    CHECK(found_mux1);
    CHECK(found_mux2);
    CHECK(found_mux3);

    vpr_free_all(arch, vpr_setup);
}

} // namespace
