#include "eval_op_prototypes.h"

eval_op_prototypes::eval_op_prototypes() {
    eval_const::store_prototype(proto_map_);
    eval_input::store_prototype(proto_map_);
    eval_add::store_prototype(proto_map_);
    eval_sub::store_prototype(proto_map_);
    eval_mul::store_prototype(proto_map_);
    eval_relu::store_prototype(proto_map_);
    eval_flatten::store_prototype(proto_map_);
    eval_input2d::store_prototype(proto_map_);
    eval_linear::store_prototype(proto_map_);
    eval_maxpool2d::store_prototype(proto_map_);
    eval_conv2d::store_prototype(proto_map_);
    //log_proto_types(); // used this when troubleshooting. uncomment to enable log
}

void eval_op_prototypes::log_proto_types() {
    std::cout << "eval_op_prototypes: registering prototypes begin:" << std::endl;
    std::cout << "----------------------" << std::endl;
    for (const auto& pair : proto_map_) {
        std::cout << "eval_op_prototypes: registered prototype: " << pair.first << std::endl;
    }
    std::cout << "----------------------" << std::endl;
    std::cout << "eval_op_prototypes: registering prototypes complete" << std::endl;

}

std::shared_ptr<eval_op> eval_op_prototypes::locate(std::string name)
{
    auto found = proto_map_.find(name);

    if (found != proto_map_.end()) {
        return found->second;
    } else {
        std::string error_message = "eval_op_prototypes: prototype for operator '" + name + "' not found.";
        std::cerr << error_message << std::endl;
        throw std::runtime_error(error_message);
    }
}

eval_op_prototypes &eval_op_prototypes::instance()
{
    static eval_op_prototypes instance; // the only instance
    return instance;
}