#include "catch.hpp"

#include "read_xml_arch_file.h"
#include "rr_metadata.h"
#include "rr_graph_writer.h"
#include "arch_util.h"
#include "vpr_api.h"
#include <cstring>

namespace {

using Catch::Matchers::Equals;

static constexpr const char kArchFile[] = "test_read_arch_metadata.xml";
static constexpr const char kRrGraphFile[] = "test_read_rrgraph_metadata.xml";

TEST_CASE("read_arch_metadata", "[vpr]") {
    t_arch arch;
    t_type_descriptor* types;
    int num_types;

    XmlReadArch(kArchFile, /*timing_enabled=*/false,
                &arch, &types, &num_types);

    bool found_perimeter_meta = false;
    bool found_single_meta = false;
    for (const auto& grid_def : arch.grid_layouts) {
        for (const auto& loc_def : grid_def.loc_defs) {
            if (loc_def.block_type == "io") {
                REQUIRE(loc_def.meta != nullptr);
                REQUIRE(loc_def.meta->has("type"));
                auto* value = loc_def.meta->one("type");
                REQUIRE(value != nullptr);
                CHECK_THAT(value->as_string(), Equals("io"));
                found_perimeter_meta = true;
            }

            if (loc_def.block_type == "clb" && loc_def.x.start_expr == "5" && loc_def.y.start_expr == "5") {
                REQUIRE(loc_def.meta != nullptr);
                REQUIRE(loc_def.meta->has("single"));
                auto* value = loc_def.meta->one("single");
                REQUIRE(value != nullptr);
                CHECK_THAT(value->as_string(), Equals("clb"));
                found_single_meta = true;
            }
        }
    }

    CHECK(found_perimeter_meta);
    CHECK(found_single_meta);

    bool found_pb_type = false;
    bool found_mode = false;
    bool found_direct = false;

    for (int i = 0; i < num_types; ++i) {
        if (strcmp("io", types[i].name) == 0) {
            found_pb_type = true;
            REQUIRE(types[i].pb_type != nullptr);
            REQUIRE(types[i].pb_type->meta.has("pb_type_type"));
            auto* pb_type_value = types[i].pb_type->meta.one("pb_type_type");
            REQUIRE(pb_type_value != nullptr);
            CHECK_THAT(pb_type_value->as_string(), Equals("pb_type = io"));

            REQUIRE(types[i].pb_type->num_modes > 0);
            REQUIRE(types[i].pb_type->modes != nullptr);

            for (int imode = 0; imode < types[i].pb_type->num_modes; ++imode) {
                if (strcmp("inpad", types[i].pb_type->modes[imode].name) == 0) {
                    found_mode = true;
                    const auto* mode = &types[i].pb_type->modes[imode];

                    REQUIRE(mode->meta.has("mode"));
                    auto* mode_value = mode->meta.one("mode");
                    REQUIRE(mode_value != nullptr);
                    CHECK_THAT(mode_value->as_string(), Equals("inpad"));

                    CHECK(mode->num_interconnect > 0);
                    REQUIRE(mode->interconnect != nullptr);

                    for (int iint = 0; iint < mode->num_interconnect; ++iint) {
                        if (strcmp("inpad", mode->interconnect[iint].name) == 0) {
                            found_direct = true;
                            REQUIRE(mode->interconnect[iint].meta.has("interconnect"));
                            auto* interconnect_value = mode->interconnect[iint].meta.one("interconnect");
                            REQUIRE(interconnect_value != nullptr);
                            CHECK_THAT(interconnect_value->as_string(), Equals("inpad_iconnect"));
                            break;
                        }
                    }
                    break;
                }
            }
            break;
        }
    }

    CHECK(found_pb_type);
    CHECK(found_mode);
    CHECK(found_direct);

    free_type_descriptors(types, num_types);
    free_arch(&arch);
}

TEST_CASE("read_rr_graph_metadata", "[vpr]") {
    int src_inode = -1;
    int sink_inode = -1;
    short switch_id = -1;

    {
        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);
        vpr_create_device(vpr_setup, arch);

        const auto& device_ctx = g_vpr_ctx.device();

        for (int inode = 0; inode < (int)device_ctx.rr_nodes.size(); ++inode) {
            if ((device_ctx.rr_nodes[inode].type() == CHANX || device_ctx.rr_nodes[inode].type() == CHANY) && device_ctx.rr_nodes[inode].num_edges() > 0) {
                src_inode = inode;
                break;
            }
        }

        REQUIRE(src_inode != -1);
        sink_inode = device_ctx.rr_nodes[src_inode].edge_sink_node(0);
        switch_id = device_ctx.rr_nodes[src_inode].edge_switch(0);

        vpr::add_rr_node_metadata(src_inode, "node", "test node");
        vpr::add_rr_edge_metadata(src_inode, sink_inode, switch_id, "edge", "test edge");

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

    REQUIRE(src_inode != -1);
    REQUIRE(sink_inode != -1);
    REQUIRE(switch_id != -1);

    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_create_device(vpr_setup, arch);

    const auto& device_ctx = g_vpr_ctx.device();
    CHECK(device_ctx.rr_node_metadata.size() == 1);
    CHECK(device_ctx.rr_edge_metadata.size() == 1);

    for (const auto& node_meta : device_ctx.rr_node_metadata) {
        CHECK(node_meta.first == src_inode);
        REQUIRE(node_meta.second.has("node"));
        auto* value = node_meta.second.one("node");
        REQUIRE(value != nullptr);
        CHECK_THAT(value->as_string(), Equals("test node"));
    }

    for (const auto& edge_meta : device_ctx.rr_edge_metadata) {
        CHECK(std::get<0>(edge_meta.first) == src_inode);
        CHECK(std::get<1>(edge_meta.first) == sink_inode);
        CHECK(std::get<2>(edge_meta.first) == switch_id);

        REQUIRE(edge_meta.second.has("edge"));
        auto* value = edge_meta.second.one("edge");
        REQUIRE(value != nullptr);
        CHECK_THAT(value->as_string(), Equals("test edge"));
    }
    vpr_free_all(arch, vpr_setup);
}

} // namespace
