#include "pack_patterns.h"

#include "atom_netlist.h"
#include "pb_graph_walker.h"
#include "globals.h"

#include <fstream>
#include <stack>
#include <queue>
#include <algorithm>

/*
 * Local Data Types
 */

struct t_arch_pack_pattern_connection {
    t_pb_graph_pin* from_pin;
    t_pb_graph_pin* to_pin;
    std::string pattern_name;
};

//Walks the PB graph collecting any pack patterns found on edges
class PbGraphPackPatternCollector : public PbGraphWalker {
    public:
        void on_edge(t_pb_graph_edge* edge) override {
            if (edge->num_pack_patterns < 1) return;

            for (int ipin = 0; ipin < edge->num_input_pins; ++ipin) {
                for (int opin = 0; opin < edge->num_output_pins; ++opin) {
                    for (int ipattern = 0; ipattern < edge->num_pack_patterns; ++ipattern) {
                        t_arch_pack_pattern_connection conn;
                        conn.from_pin = edge->input_pins[ipin];
                        conn.to_pin = edge->output_pins[opin];
                        conn.pattern_name = edge->pack_pattern_names[ipattern];
                        
                        pack_pattern_connections[conn.pattern_name].push_back(conn);
                    }
                }
            }
        }

        std::map<std::string,std::vector<t_arch_pack_pattern_connection>> pack_pattern_connections;
};

/*
 * Local Function Delcarations
 */
static std::map<std::string,std::vector<t_arch_pack_pattern_connection>> collect_type_pack_pattern_connections(t_type_ptr type);
static t_arch_pack_pattern build_pack_pattern(std::string pattern_name, const std::vector<t_arch_pack_pattern_connection>& connections);
static t_netlist_pack_pattern abstract_arch_pack_pattern(const t_arch_pack_pattern& arch_pack_pattern);


static NetlistPatternMatch match_largest(AtomBlockId blk, const t_netlist_pack_pattern& pattern, const AtomNetlist& netlist);
static bool match_largest_recur(NetlistPatternMatch& match, const AtomBlockId blk, 
                                int pattern_node_id, const t_netlist_pack_pattern& pattern,
                                const AtomNetlist& netlist);

static AtomPinId find_matching_pin(const AtomNetlist::pin_range pin_range, const t_netlist_pack_pattern_pin& pattern_pin, const AtomNetlist& netlist);
static bool matches_pattern_node(const AtomBlockId blk, const t_netlist_pack_pattern_node& pattern_node, const AtomNetlist& netlist);
static bool is_wildcard_node(const t_netlist_pack_pattern_node& pattern_node);
static bool is_wildcard_pin(const t_netlist_pack_pattern_pin& pattern_pin);
static bool matches_pattern_pin(const AtomPinId from_pin, const t_netlist_pack_pattern_pin& pattern_pin, const AtomNetlist& netlist);
static bool match_covered(const NetlistPatternMatch& match, const std::map<std::string,std::set<AtomBlockId>>& pattern_covered_blocks);

/*
 * Global Function Implementations
 */

std::vector<t_arch_pack_pattern> identify_arch_pack_patterns(const DeviceContext& device_ctx) {
    std::vector<t_arch_pack_pattern> arch_pack_patterns;

    //For every complex block
    for (int itype = 0; itype < device_ctx.num_block_types; ++itype) {
        //Collect the pack pattern connections defined in the architecture
        const auto& pack_pattern_connections = collect_type_pack_pattern_connections(&device_ctx.block_types[itype]);

        //vtr::printf("TYPE: %s\n", device_ctx.block_types[itype].name);

        //Convert each set of connections to an architecture pack pattern
        for (auto kv : pack_pattern_connections) {
            t_arch_pack_pattern pack_pattern = build_pack_pattern(kv.first, kv.second);

            arch_pack_patterns.push_back(pack_pattern);
        }
    }

    return arch_pack_patterns;
}

std::vector<t_netlist_pack_pattern> abstract_arch_pack_patterns(const std::vector<t_arch_pack_pattern>& arch_pack_patterns) {
    std::vector<t_netlist_pack_pattern> netlist_pack_patterns;

    for (auto arch_pattern : arch_pack_patterns) {
        auto netlist_pattern = abstract_arch_pack_pattern(arch_pattern);
        netlist_pack_patterns.push_back(netlist_pattern);

        //Debug
        std::ofstream ofs("netlist_pack_pattern." + netlist_pattern.name + ".echo");
        write_netlist_pack_pattern_dot(ofs, netlist_pattern);
    }

    return netlist_pack_patterns;
}

t_netlist_pack_pattern create_atom_default_pack_pattern() {
    t_netlist_pack_pattern atom_pack_pattern;

    //A single internal wild-card node
    atom_pack_pattern.root_node = atom_pack_pattern.create_node(false);

    atom_pack_pattern.name = ATOM_DEFAULT_PACK_PATTERN_NAME;

    return atom_pack_pattern;
}


std::vector<NetlistPatternMatch> collect_pattern_matches_in_netlist(const t_netlist_pack_pattern& pattern, const AtomNetlist& netlist) {
    std::vector<NetlistPatternMatch> matches;

    //Walk through all the blocks in the netlist and see if they match the current pattern
    //
    //Note that we walk through the blocks in topological order to ensure:
    //  1) The 'highest' block in a pattern is matched first,
    //  2) consistency, even if the blocks are re-ordered the topological structure is the same
    for (auto blk : topological_block_order(netlist)) {
        vtr::printf("Matching at block %s for pattern %s\n",
                    g_vpr_ctx.atom().nlist.block_name(blk).c_str(),
                    pattern.name.c_str());

        NetlistPatternMatch match = match_largest(blk, pattern, netlist);

        if (match) {
            vtr::printf("\tMatched!\n");
            //Save the match
            matches.push_back(match);

        }
    }

    return matches;
}

std::vector<NetlistPatternMatch> filter_netlist_pattern_matches(std::vector<NetlistPatternMatch> unfiltered_matches) {
    std::vector<NetlistPatternMatch> filtered_matches;

    //Sort the matches in descending order based on the following criteria:
    //   1) Size
    //   2) Base cost
    //Note that we use a stable sort to maintain the topological order in which the matches were found
    auto by_preference = [&](const NetlistPatternMatch& lhs, const NetlistPatternMatch& rhs) {
        return std::make_tuple(lhs.internal_blocks.size(), lhs.base_cost) > 
               std::make_tuple(rhs.internal_blocks.size(), rhs.base_cost);
    };
    std::stable_sort(unfiltered_matches.begin(), unfiltered_matches.end(), by_preference);


    std::map<std::string,std::set<AtomBlockId>> pattern_covered_blocks;
    for (auto& match : unfiltered_matches) {
        if (match.internal_blocks.empty()) continue; //Don't keep empty matches

        if (match_covered(match, pattern_covered_blocks)) continue; //Each atom should appear in at most one molecule per pack pattern type

        pattern_covered_blocks[match.pattern_name].insert(match.internal_blocks.begin(), match.internal_blocks.end());

        filtered_matches.push_back(match);
    }

    return filtered_matches;
}

void print_match(const NetlistPatternMatch& match, const AtomNetlist& netlist) {
    vtr::printf("Netlist Match to %s:\n", match.pattern_name.c_str());
    for (auto& edge : match.netlist_edges) {
        AtomBlockId from_blk = netlist.pin_block(edge.from_pin);
        AtomBlockId to_blk = netlist.pin_block(edge.to_pin);

        bool from_external = (std::find(match.external_blocks.begin(), match.external_blocks.end(), from_blk) != match.external_blocks.end());
        bool to_external = (std::find(match.external_blocks.begin(), match.external_blocks.end(), to_blk) != match.external_blocks.end());

        vtr::printf("  %s -> %s (%s%s -> %s%s) (pattern edge #%d.%d)\n", 
                netlist.pin_name(edge.from_pin).c_str(),
                netlist.pin_name(edge.to_pin).c_str(),
                netlist.block_model(netlist.pin_block(edge.from_pin))->name,
                (from_external) ? "*" : "",
                netlist.block_model(netlist.pin_block(edge.to_pin))->name,
                (to_external) ? "*" : "",
                edge.pattern_edge_id,
                edge.pattern_edge_sink);
    }

    for (auto blk : match.internal_blocks) {
        vtr::printf("\tInternal match block: %s (%zu)\n", netlist.block_name(blk).c_str(), size_t(blk));
    }

    for (auto blk : match.external_blocks) {
        vtr::printf("\tExternal match block: %s (%zu)\n", netlist.block_name(blk).c_str(), size_t(blk));
    }
}

void write_arch_pack_pattern_dot(std::ostream& os, const t_arch_pack_pattern& arch_pattern) {
    os << "#Dot file of architecture pack pattern graph\n";
    os << "digraph " << arch_pattern.name << " {\n";

    for (size_t inode = 0; inode < arch_pattern.nodes.size(); ++inode) {
        os << "N" << inode;
        
        os << " [";

        os << "label=\"" << describe_pb_graph_pin_hierarchy(arch_pattern.nodes[inode].pb_graph_pin) << " (#" << inode << ")\"";

        os << "];\n";
    }

    for (size_t iedge = 0; iedge < arch_pattern.edges.size(); ++iedge) {
        os << "N" << arch_pattern.edges[iedge].from_node_id << " -> N" << arch_pattern.edges[iedge].to_node_id;
        os << " [";

        os << "label=\"" ;
        os << "(#" << iedge << ")";
        os << "\"";

        os << "];\n";
    }

    os << "}\n";
}

void write_netlist_pack_pattern_dot(std::ostream& os, const t_netlist_pack_pattern& netlist_pattern) {
    os << "#Dot file of netlist pack pattern graph\n";
    os << "digraph " << netlist_pattern.name << " {\n";

    //Nodes
    for (size_t inode = 0; inode < netlist_pattern.nodes.size(); ++inode) {
        os << "N" << inode;
        
        os << " [";

        os << "label=\"";
        if (netlist_pattern.nodes[inode].model_type) {
            os << netlist_pattern.nodes[inode].model_type->name;
        } else {
            os << "*";
        }
        os << " (#" << inode << ")";
        os << "\"";

        if (netlist_pattern.nodes[inode].is_external()) {
            os << " shape=invhouse";
        }

        os << "];\n";
    }

    //Edges
    for (size_t iedge = 0; iedge < netlist_pattern.edges.size(); ++iedge) {
        const auto& edge = netlist_pattern.edges[iedge];

        const auto& from_pin = edge.from_pin;
        for (size_t isink = 0; isink < edge.to_pins.size(); ++isink) {
            const auto& to_pin = edge.to_pins[isink];

            os << "N" << edge.from_pin.node_id << " -> N" << edge.to_pins[isink].node_id;
            os << " [";

            os << "label=\"" ;

            os << "(#" << iedge << "." << isink << ")\\n";
            if (is_wildcard_pin(from_pin)) {
                os << "*";
            } else {
                os << from_pin.model_port->name << "[" << from_pin.port_pin << "]";
            }
            os << "\\n -> ";
            if (is_wildcard_pin(to_pin)) {
                os << "*";
            } else {
                os << to_pin.model_port->name << "[" << to_pin.port_pin << "]";
            }
            os << "\"";

            if (to_pin.required) {
                os << " style=solid";
            } else {
                os << " style=dashed";
            }

            os << "];\n";
        }
    }

    os << "}\n";
}
/*
 * Local Function Implementations
 */
static std::map<std::string,std::vector<t_arch_pack_pattern_connection>> collect_type_pack_pattern_connections(t_type_ptr type) {
    PbGraphPackPatternCollector collector;

    collector.walk(type->pb_graph_head);

    return collector.pack_pattern_connections;
}

static t_arch_pack_pattern build_pack_pattern(std::string pattern_name, const std::vector<t_arch_pack_pattern_connection>& connections) {
    t_arch_pack_pattern pack_pattern;
    pack_pattern.name = pattern_name;

    for (auto conn : connections) {
        vtr::printf("pack_pattern '%s' conn: %s -> %s\n", 
                    conn.pattern_name.c_str(),
                    describe_pb_graph_pin_hierarchy(conn.from_pin).c_str(),
                    describe_pb_graph_pin_hierarchy(conn.to_pin).c_str());
    }

    //Create the nodes
    std::map<t_pb_graph_pin*, int> pb_graph_pin_to_pattern_node_id;
    for (auto conn : connections) {
        VTR_ASSERT(conn.pattern_name == pattern_name);

        t_pb_graph_pin* from_pin = conn.from_pin;
        t_pb_graph_pin* to_pin = conn.to_pin;

        if (from_pin) {
            if (!pb_graph_pin_to_pattern_node_id.count(from_pin)) {
                //Create
                int pattern_node_id = pack_pattern.nodes.size();
                pack_pattern.nodes.emplace_back(from_pin);

                //Save ID
                pb_graph_pin_to_pattern_node_id[from_pin] = pattern_node_id;
            }
        }

        if (to_pin) {
            if (!pb_graph_pin_to_pattern_node_id.count(to_pin)) {
                //Create
                int pattern_node_id = pack_pattern.nodes.size();
                pack_pattern.nodes.emplace_back(to_pin);

                //Save ID
                pb_graph_pin_to_pattern_node_id[to_pin] = pattern_node_id;
            }
        }
    }

    //Create the edges
    std::map<std::pair<t_pb_graph_pin*,t_pb_graph_pin*>, int> conn_to_pattern_edge;
    for (auto conn : connections) {
        auto key = std::make_pair(conn.from_pin, conn.to_pin);
        if (!conn_to_pattern_edge.count(key)) {
            //Find connected nodes
            VTR_ASSERT(pb_graph_pin_to_pattern_node_id.count(conn.from_pin));
            VTR_ASSERT(pb_graph_pin_to_pattern_node_id.count(conn.to_pin));
            int from_node_id = pb_graph_pin_to_pattern_node_id[conn.from_pin];
            int to_node_id = pb_graph_pin_to_pattern_node_id[conn.to_pin];

            //Create edge
            int edge_id = pack_pattern.edges.size();
            pack_pattern.edges.emplace_back(); 

            pack_pattern.edges[edge_id].from_node_id = from_node_id;
            pack_pattern.edges[edge_id].to_node_id = to_node_id;

            //Save ID
            conn_to_pattern_edge[key] = edge_id;


            //Add edge references to connected nodes
            pack_pattern.nodes[from_node_id].out_edge_ids.push_back(edge_id);
            pack_pattern.nodes[to_node_id].in_edge_ids.push_back(edge_id);
        }
    }

    //Record roots
    for (size_t inode = 0; inode < pack_pattern.nodes.size(); ++inode) {
        if (pack_pattern.nodes[inode].in_edge_ids.empty()) {
            pack_pattern.root_node_ids.push_back(inode);
        }
    }

    //Calculate the base cost of the pattern based on the nodes involved
    std::set<t_pb_graph_node*> seen_pb_graph_nodes;
    for (size_t inode = 0; inode < pack_pattern.nodes.size(); ++inode) {
        t_pb_graph_node* pb_graph_node = pack_pattern.nodes[inode].pb_graph_pin->parent_node;

        if (seen_pb_graph_nodes.count(pb_graph_node)) continue;

        pack_pattern.base_cost += compute_primitive_base_cost(pb_graph_node);
    }

    return pack_pattern;
}


static t_netlist_pack_pattern abstract_arch_pack_pattern(const t_arch_pack_pattern& arch_pattern) {
    t_netlist_pack_pattern netlist_pattern;
    netlist_pattern.name = arch_pattern.name;
    netlist_pattern.base_cost = arch_pattern.base_cost;

    struct EdgeInfo {
        EdgeInfo(int from_node, int from_edge, int via_edge, int curr_node)
            : from_arch_node(from_node)
            , from_arch_edge(from_edge)
            , via_arch_edge(via_edge)
            , curr_arch_node(curr_node) {}

        int from_arch_node = OPEN; //Last primitive node we came from
        int from_arch_edge = OPEN; //Last primitive edge we came from
        int via_arch_edge = OPEN; //Edge to current node
        int curr_arch_node = OPEN; //Current node

    };


    //Breadth-First Traversal of arch pack pattern graph, 
    //to record which primitives are reachable from each other.
    //
    //The resulting edges are abstracted from the 
    //pb_graph hierarchy and contain only primitives (no intermediate
    //hiearchy)
    //
    //Note that to get the full set of possible edges we perform a BFT
    //from each primitive/top-level node
    std::vector<EdgeInfo> arch_abstract_edges;
    for (int root_node : arch_pattern.root_node_ids) {
        std::set<int> visited;
        std::queue<EdgeInfo> q;

        vtr::printf("BFT from root %d\n", root_node);

        q.emplace(OPEN, OPEN, OPEN, root_node); //Starting at root

        while (!q.empty()) {
            EdgeInfo info = q.front();
            q.pop();

            int curr_node = info.curr_arch_node;

            if (visited.count(curr_node)) continue; //Don't revisit to avoid loops
            visited.insert(curr_node);
            
            bool is_primitive = arch_pattern.nodes[curr_node].pb_graph_pin->parent_node->is_primitive();
            bool is_top = arch_pattern.nodes[curr_node].pb_graph_pin->parent_node->is_top_level();
            vtr::printf(" Visiting %d via %d (is_prim: %d)\n", curr_node, info.via_arch_edge, is_primitive);

            if ((is_primitive || is_top) && info.from_arch_edge != OPEN && info.via_arch_edge != OPEN) {
                //Record the primitive-to-primitive edge used to reach this node
                arch_abstract_edges.push_back(info);
                vtr::printf("  Recording Abstract Edge from node %d (via edge %d) -> node %d (via edge %d)\n", info.from_arch_node, info.from_arch_edge, curr_node, info.via_arch_edge);
            }

            //Expand out edges
            for (auto out_edge : arch_pattern.nodes[curr_node].out_edge_ids) {

                int next_node = arch_pattern.edges[out_edge].to_node_id;

                if (is_primitive || curr_node == root_node) {
                    //Expanding from a primitive, use the current node as from
                    q.emplace(curr_node, out_edge, out_edge, next_node);
                } else {
                    //Expanding from a non-primitive, re-use the previous primtiive as from
                    q.emplace(info.from_arch_node, info.from_arch_edge, out_edge, next_node);
                }
            }
        }
    }


    //
    //Build the netlist pattern from the edges collected above
    //
    std::map<t_pb_graph_pin*,int> pb_graph_pin_to_netlist_pattern_node;
    std::map<t_pb_graph_node*,int> pb_graph_node_to_netlist_pattern_node;

    std::map<t_pb_graph_pin*,int> pb_graph_pin_to_netlist_pattern_edge;

    for (auto arch_abstract_edge : arch_abstract_edges) {

        //Find or create from node
        int netlist_from_node = OPEN;
        t_pb_graph_pin* from_pin = arch_pattern.nodes[arch_abstract_edge.from_arch_node].pb_graph_pin;
        if (pb_graph_pin_to_netlist_pattern_node.count(from_pin)) {
            //Existing
            netlist_from_node = pb_graph_pin_to_netlist_pattern_node[from_pin];
        } else if (pb_graph_node_to_netlist_pattern_node.count(from_pin->parent_node)) {
            //Existing
            netlist_from_node = pb_graph_node_to_netlist_pattern_node[from_pin->parent_node];
        } else if (from_pin->parent_node->is_top_level()) {
            //Create
            netlist_from_node = netlist_pattern.create_node(true);

            //Default initialization

            //Save Id
            pb_graph_pin_to_netlist_pattern_node[from_pin] = netlist_from_node;
        } else {
            //Create
            netlist_from_node = netlist_pattern.create_node(false);

            //Initialize
            netlist_pattern.nodes[netlist_from_node].model_type = from_pin->parent_node->pb_type->model;

            //Save Id
            pb_graph_node_to_netlist_pattern_node[from_pin->parent_node] = netlist_from_node;
        }
        VTR_ASSERT(netlist_from_node != OPEN);

        //Find or create to node
        int netlist_to_node = OPEN;
        t_pb_graph_pin* to_pin = arch_pattern.nodes[arch_abstract_edge.curr_arch_node].pb_graph_pin;
        if (pb_graph_pin_to_netlist_pattern_node.count(to_pin)) {
            //Existing
            netlist_to_node = pb_graph_pin_to_netlist_pattern_node[to_pin];
        } else if (pb_graph_node_to_netlist_pattern_node.count(to_pin->parent_node)) {
            //Existing
            netlist_to_node = pb_graph_node_to_netlist_pattern_node[to_pin->parent_node];
        } else if (to_pin->parent_node->is_top_level()) {
            //Create
            netlist_to_node = netlist_pattern.create_node(true);

            //Default initialization

            //Save Id
            pb_graph_pin_to_netlist_pattern_node[to_pin] = netlist_to_node;
        } else {
            //Create
            netlist_to_node = netlist_pattern.create_node(false);

            //Initialize
            netlist_pattern.nodes[netlist_to_node].model_type = to_pin->parent_node->pb_type->model;

            //Save Id
            pb_graph_node_to_netlist_pattern_node[to_pin->parent_node] = netlist_to_node;
        }
        VTR_ASSERT(netlist_to_node != OPEN);

        //Create edge

        int netlist_edge = OPEN;
        if (pb_graph_pin_to_netlist_pattern_edge.count(from_pin)) {
            //Existing
            netlist_edge = pb_graph_pin_to_netlist_pattern_edge[from_pin];
        } else {
            //create
            netlist_edge = netlist_pattern.create_edge();

            //Initialize
            netlist_pattern.edges[netlist_edge].from_pin.node_id = netlist_from_node;
            if (!pb_graph_pin_to_netlist_pattern_node.count(from_pin)) {
                //Only initialze these fields for non source/sink
                netlist_pattern.edges[netlist_edge].from_pin.model = from_pin->parent_node->pb_type->model;
                netlist_pattern.edges[netlist_edge].from_pin.model_port = from_pin->port->model_port;
                netlist_pattern.edges[netlist_edge].from_pin.port_pin = from_pin->pin_number;
            }

            //Update node ref
            netlist_pattern.nodes[netlist_from_node].out_edge_ids.push_back(netlist_edge);

            //Save Id
            pb_graph_pin_to_netlist_pattern_edge[from_pin] = netlist_edge;
        }

        //Add sink
        t_netlist_pack_pattern_pin sink_pin;
        sink_pin.node_id = netlist_to_node;
        if (!pb_graph_pin_to_netlist_pattern_node.count(to_pin)) {
            sink_pin.model = to_pin->parent_node->pb_type->model;
            sink_pin.model_port = to_pin->port->model_port;
            sink_pin.port_pin = to_pin->pin_number;
        }

        netlist_pattern.edges[netlist_edge].to_pins.push_back(sink_pin);

        //Update node refs
        netlist_pattern.nodes[netlist_to_node].in_edge_ids.push_back(netlist_edge);
    }

    //Record the roots
    std::vector<int> roots;
    for (size_t inode = 0; inode < netlist_pattern.nodes.size(); ++inode) {
        if (netlist_pattern.nodes[inode].is_root()) {
            roots.push_back(inode);
        }
    }

    //Should have a single root
    if (roots.size() == 1) {
        VTR_ASSERT(netlist_pattern.root_node == OPEN);
        netlist_pattern.root_node = roots[0];
    } else {
        std::string msg = vtr::string_fmt("Pack pattern '%s' has multiple roots (pack pattern "
                                          "connection(s) are likely missing causing the pattern "
                                          "to be disconnected)\n",
                                          netlist_pattern.name.c_str());

        msg += vtr::string_fmt("  Involved nodes:\n");
        for (auto root : roots) {
            if (netlist_pattern.nodes[root].model_type) {
                msg += vtr::string_fmt("%s\n", netlist_pattern.nodes[root].model_type->name);
            }
        }

        VPR_THROW(VPR_ERROR_ARCH, msg.c_str());
    }
    VTR_ASSERT(netlist_pattern.root_node != OPEN);

    return netlist_pattern;
}

static NetlistPatternMatch match_largest(AtomBlockId blk, const t_netlist_pack_pattern& pattern, const AtomNetlist& netlist) {
    NetlistPatternMatch match;
    match.pattern_name = pattern.name;
    match.base_cost = pattern.base_cost;


    //Prefer matching to an internal node first (i.e. skipping the first external node),
    //provided it has only a single fanout to an internal node
    //
    //For instance, this allows us to match a carry-chain, even if there is no net driving the chain input.
    bool pattern_root_external = pattern.nodes[pattern.root_node].is_external();
    bool pattern_root_single_fanout = (pattern.nodes[pattern.root_node].out_edge_ids.size() == 1);
    if (pattern_root_external && pattern_root_single_fanout) {
        VTR_ASSERT_MSG(pattern.nodes[pattern.root_node].out_edge_ids.size() == 1, "Assume single fanout external root");
        int pattern_edge_id = pattern.nodes[pattern.root_node].out_edge_ids[0];
        const auto& pattern_edge = pattern.edges[pattern_edge_id];
        if (pattern_edge.to_pins.size() == 1) { //If a pattern has multiple fanout from external route we can't match to internal
            const auto& to_pattern_pin = pattern_edge.to_pins[0];
            const auto& to_pattern_node = pattern.nodes[to_pattern_pin.node_id];
            VTR_ASSERT_MSG(to_pattern_node.is_internal(), "Assume single level of external root nodes");

            //Match to the first internal node
            if (match_largest_recur(match, blk, to_pattern_pin.node_id, pattern, netlist)) {
                return match;
            }
        }
    }

    //Fall back to matching external root node
    if (match_largest_recur(match, blk, pattern.root_node, pattern, netlist)) {
        return match; 
    }

    return NetlistPatternMatch(); //No match, return empty
}

static bool match_largest_recur(NetlistPatternMatch& match, const AtomBlockId blk, 
                                int pattern_node_id, const t_netlist_pack_pattern& pattern,
                                const AtomNetlist& netlist) {

    if (!matches_pattern_node(blk, pattern.nodes[pattern_node_id], netlist)) {
        return false; 
    }

    bool pattern_node_internal = pattern.nodes[pattern_node_id].is_internal();
    if (pattern_node_internal) {
        match.internal_blocks.push_back(blk);
    } else {
        VTR_ASSERT(pattern.nodes[pattern_node_id].is_external());
        match.external_blocks.push_back(blk);
    }

    for (int pattern_edge_id : pattern.nodes[pattern_node_id].out_edge_ids) {
        const auto& pattern_edge = pattern.edges[pattern_edge_id];
        const auto& from_pattern_pin = pattern_edge.from_pin;

        AtomPinId from_pin = find_matching_pin(netlist.block_output_pins(blk), from_pattern_pin, netlist);

        if (!from_pin) {
            //No matching driver pin
            if (from_pattern_pin.required) {
                //Required: give-up
                return false;
            } else {
                //Optional: try next edge
                continue;
            }
        }

        AtomNetId net = netlist.pin_net(from_pin);
        auto net_sinks = netlist.net_sinks(net);

        for (size_t isink = 0; isink < pattern_edge.to_pins.size(); ++isink) {
            const auto& to_pattern_pin = pattern_edge.to_pins[isink];

            AtomPinId to_pin = find_matching_pin(net_sinks, to_pattern_pin, netlist);
            if (!to_pin) {
                //No valid to_pin

                if (to_pattern_pin.required) {
                    //Required: give-up
                    return false;
                } else {
                    //Optional: try next pattern pin
                    continue;
                }
            }

            //Collect any downstream matches recursively
            AtomBlockId to_blk = netlist.pin_block(to_pin);
            bool subtree_matched = match_largest_recur(match, to_blk, to_pattern_pin.node_id, pattern, netlist);

            if (!subtree_matched) {
                if (to_pattern_pin.required) {
                    //Required: give-up
                    return false;
                } else {
                    //Optional: try next pattern pin
                    continue;
                }
            }

            //Valid match between netlist from_pin/to_pin and from_pattern_pin/to_pattern_pin
            //Add it to the match
            match.netlist_edges.emplace_back(from_pin, to_pin, pattern_edge_id, isink);
        }
    }

    return true;
}

static AtomPinId find_matching_pin(const AtomNetlist::pin_range pin_range, const t_netlist_pack_pattern_pin& pattern_pin,
                                   const AtomNetlist& netlist) {
    for (AtomPinId pin : pin_range) {
        if (matches_pattern_pin(pin, pattern_pin, netlist)) {
            return pin;
        }
    }
    return AtomPinId::INVALID(); //No match
}

static bool matches_pattern_node(const AtomBlockId blk, const t_netlist_pack_pattern_node& pattern_node, const AtomNetlist& netlist) {
    if (is_wildcard_node(pattern_node)) {
        return true; //Wildcard
    }
    return netlist.block_model(blk) == pattern_node.model_type;
}

static bool is_wildcard_node(const t_netlist_pack_pattern_node& pattern_node) {
    return pattern_node.model_type == nullptr;
}

static bool is_wildcard_pin(const t_netlist_pack_pattern_pin& pattern_pin) {
    return (pattern_pin.model == nullptr
            && pattern_pin.model_port == nullptr
            && pattern_pin.port_pin == OPEN);
}

static bool matches_pattern_pin(const AtomPinId from_pin, const t_netlist_pack_pattern_pin& pattern_pin, const AtomNetlist& netlist) {

    if (is_wildcard_pin(pattern_pin)) {
        return true; //Wildcard
    }

    if (netlist.block_model(netlist.pin_block(from_pin)) != pattern_pin.model
        || netlist.port_model(netlist.pin_port(from_pin)) != pattern_pin.model_port
        || netlist.pin_port_bit(from_pin) != (BitIndex) pattern_pin.port_pin) {
        return false;
    }

    return true;
}

static bool match_covered(const NetlistPatternMatch& match, const std::map<std::string,std::set<AtomBlockId>>& pattern_covered_blocks) {
    for (auto blk : match.internal_blocks) {
        auto itr = pattern_covered_blocks.find(match.pattern_name);
        if (itr != pattern_covered_blocks.end() && itr->second.count(blk)) return true; 
    }
    return false;
}

