#include "vtr_assert.h"
#include "vtr_log.h"

#include "atom_lookup.h"
/*
 * PB
 */
const t_pb* AtomLookup::atom_pb(const AtomBlockId blk_id) const {
    auto iter = atom_to_pb_.find(blk_id);
    if(iter == atom_to_pb_.end()) {
        //Not found
        return nullptr;
    }
    return iter->second;
}

AtomBlockId AtomLookup::pb_atom(const t_pb* pb) const {
    auto iter = atom_to_pb_.find(pb);
    if(iter == atom_to_pb_.inverse_end()) {
        //Not found
        return AtomBlockId::INVALID();
    }
    return iter->second;
}

const t_pb_graph_node* AtomLookup::atom_pb_graph_node(const AtomBlockId blk_id) const {
    const t_pb* pb = atom_pb(blk_id);
    if(pb) {
        //Found
        return pb->pb_graph_node;
    }
    return nullptr;
}

void AtomLookup::set_atom_pb(const AtomBlockId blk_id, const t_pb* pb) {
    //If either of blk_id or pb are not valid,
    //remove any mapping

    if(!blk_id && pb) {
        //Remove
        atom_to_pb_.erase(pb);
    } else if(blk_id && !pb) {
        //Remove
        atom_to_pb_.erase(blk_id);
    } else if(blk_id && pb) {
        //If both are valid store the mapping
        atom_to_pb_.update(blk_id, pb);
    }
}

/*
 * PB Pins
 */
const t_pb_graph_pin* AtomLookup::atom_pin_pb_graph_pin(AtomPinId atom_pin) const {
    return atom_pin_to_pb_graph_pin_[atom_pin];
}

void AtomLookup::set_atom_pin_pb_graph_pin(AtomPinId atom_pin, const t_pb_graph_pin* gpin) {
    atom_pin_to_pb_graph_pin_.insert(atom_pin, gpin);
}

/*
 * Blocks
 */
ClusterBlockId AtomLookup::atom_clb(const AtomBlockId blk_id) const {
    VTR_ASSERT(blk_id);
    auto iter = atom_to_clb_.find(blk_id);
    if(iter == atom_to_clb_.end()) {
        return ClusterBlockId::INVALID();
    }

    return *iter;
}

void AtomLookup::set_atom_clb(const AtomBlockId blk_id, const ClusterBlockId clb) {
    VTR_ASSERT(blk_id);

    atom_to_clb_.update(blk_id, clb);
}

/*
 * Nets
 */
AtomNetId AtomLookup::atom_net(const ClusterNetId clb_net_index) const {
    auto iter = atom_net_to_clb_net_.find(clb_net_index);
    if(iter == atom_net_to_clb_net_.inverse_end()) {
        //Not found
        return AtomNetId::INVALID();
    }
    return iter->second;
}

ClusterNetId AtomLookup::clb_net(const AtomNetId net_id) const {
    auto iter = atom_net_to_clb_net_.find(net_id);
    if(iter == atom_net_to_clb_net_.end()) {
        //Not found
        return ClusterNetId::INVALID();
    }
    return iter->second;

}


void AtomLookup::set_atom_clb_net(const AtomNetId net_id, const ClusterNetId clb_net_index) {
    VTR_ASSERT(net_id);
    //If either are invalid remove any mapping
    if(!net_id && clb_net_index != ClusterNetId::INVALID()) {
        //Remove
        atom_net_to_clb_net_.erase(clb_net_index);
    } else if(net_id && clb_net_index == ClusterNetId::INVALID()) {
        //Remove
        atom_net_to_clb_net_.erase(net_id);
    } else if (net_id && clb_net_index != ClusterNetId::INVALID()) {
        //Store
        atom_net_to_clb_net_.update(net_id, clb_net_index);
    }
}

/*
 * Classic Timing nodes
 */
AtomPinId AtomLookup::classic_tnode_atom_pin(const int tnode_index) const {
    auto iter = atom_pin_to_classic_tnode_.find(tnode_index);
    if(iter == atom_pin_to_classic_tnode_.inverse_end()) {
        //Not found
        return AtomPinId::INVALID();
    }
    return iter->second;
}

int AtomLookup::atom_pin_classic_tnode(const AtomPinId pin_id) const {
    auto iter = atom_pin_to_classic_tnode_.find(pin_id);
    if(iter == atom_pin_to_classic_tnode_.end()) {
        //Not found
        return OPEN;
    }
    return iter->second;

}


void AtomLookup::set_atom_pin_classic_tnode(const AtomPinId pin_id, const int tnode_index) {
    VTR_ASSERT(pin_id);
    //If either are invalid remove any mapping
    if(!pin_id && tnode_index != OPEN) {
        //Remove
        atom_pin_to_classic_tnode_.erase(tnode_index);
    } else if(pin_id && tnode_index == OPEN) {
        //Remove
        atom_pin_to_classic_tnode_.erase(pin_id);
    } else if(pin_id && tnode_index != OPEN) {
        //Store
        atom_pin_to_classic_tnode_.update(pin_id, tnode_index);
    }
}

/*
 * Timing Nodes
 */
tatum::NodeId AtomLookup::atom_pin_tnode(const AtomPinId pin, BlockTnode block_tnode_type) const {
    if(block_tnode_type == BlockTnode::EXTERNAL) {
        auto iter = atom_pin_tnode_external_.find(pin);
        if(iter != atom_pin_tnode_external_.end()) {
            return iter->second;
        }
    } else {
        VTR_ASSERT(block_tnode_type == BlockTnode::INTERNAL);
        auto iter = atom_pin_tnode_internal_.find(pin);
        if(iter != atom_pin_tnode_internal_.end()) {
            return iter->second;
        }
    }

    return tatum::NodeId::INVALID(); //Not found
}

AtomPinId AtomLookup::tnode_atom_pin(const tatum::NodeId tnode) const {
    auto iter = tnode_atom_pin_.find(tnode);
    if(iter != tnode_atom_pin_.end()) {
        return iter->second;
    }

    return AtomPinId::INVALID(); //Not found
}

AtomLookup::tnode_pin_range AtomLookup::tnode_atom_pins() const {
    return vtr::make_range(tnode_atom_pin_.begin(), tnode_atom_pin_.end());
}

void AtomLookup::set_atom_pin_tnode(const AtomPinId pin, const tatum::NodeId node, BlockTnode block_tnode_type) {

    //A pin always expands to an external tnode (i.e. it's external connectivity in the netlist)
    //but some pins may expand to an additional tnode (i.e. to SOURCE/SINK to cover internal sequential paths within a block)
    if(block_tnode_type == BlockTnode::EXTERNAL) {
        atom_pin_tnode_external_[pin] = node;
    } else {
        VTR_ASSERT(block_tnode_type == BlockTnode::INTERNAL);
        atom_pin_tnode_internal_[pin] = node;
    }

    //Each tnode maps to precisely one pin
    tnode_atom_pin_[node] = pin;
}
