#include <cstring>
#include <vector>
#include <sstream>

#include "vtr_assert.h"
#include "vtr_util.h"
#include "vtr_random.h"
#include "vtr_log.h"
#include "vtr_memory.h"
#include "vtr_time.h"

#include "vpr_types.h"
#include "vpr_error.h"
#include "vpr_utils.h"

#include "globals.h"
#include "read_xml_arch_file.h"
#include "SetupVPR.h"
#include "pb_type_graph.h"
#include "pack_types.h"
#include "lb_type_rr_graph.h"
#include "rr_graph_area.h"
#include "echo_arch.h"
#include "read_options.h"
#include "echo_files.h"
#include "clock_modeling.h"

static void SetupNetlistOpts(const t_options& Options, t_netlist_opts& NetlistOpts);
static void SetupPackerOpts(const t_options& Options,
                            t_packer_opts* PackerOpts);
static void SetupPlacerOpts(const t_options& Options,
                            t_placer_opts* PlacerOpts);
static void SetupAnnealSched(const t_options& Options,
                             t_annealing_sched* AnnealSched);
static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts);
static void SetupRoutingArch(const t_arch& Arch, t_det_routing_arch* RoutingArch);
static void SetupTiming(const t_options& Options, const bool TimingEnabled, t_timing_inf* Timing);
static void SetupSwitches(const t_arch& Arch,
                          t_det_routing_arch* RoutingArch,
                          const t_arch_switch_inf* ArchSwitches,
                          int NumArchSwitches);
static void SetupAnalysisOpts(const t_options& Options, t_analysis_opts& analysis_opts);
static void SetupPowerOpts(const t_options& Options, t_power_opts* power_opts, t_arch* Arch);
static int find_ipin_cblock_switch_index(const t_arch& Arch);

/* Sets VPR parameters and defaults. Does not do any error checking
 * as this should have been done by the various input checkers */
void SetupVPR(const t_options* Options,
              const bool TimingEnabled,
              const bool readArchFile,
              t_file_name_opts* FileNameOpts,
              t_arch* Arch,
              t_model** user_models,
              t_model** library_models,
              t_netlist_opts* NetlistOpts,
              t_packer_opts* PackerOpts,
              t_placer_opts* PlacerOpts,
              t_annealing_sched* AnnealSched,
              t_router_opts* RouterOpts,
              t_analysis_opts* AnalysisOpts,
              t_det_routing_arch* RoutingArch,
              std::vector<t_lb_type_rr_node>** PackerRRGraphs,
              std::vector<t_segment_inf>& Segments,
              t_timing_inf* Timing,
              bool* ShowGraphics,
              int* GraphPause,
              bool* SaveGraphics,
              t_power_opts* PowerOpts) {
    using argparse::Provenance;

    auto& device_ctx = g_vpr_ctx.mutable_device();

    if (Options->CircuitName.value() == "") {
        VPR_FATAL_ERROR(VPR_ERROR_BLIF_F,
                        "No blif file found in arguments (did you specify an architecture file?)\n");
    }

    alloc_and_load_output_file_names(Options->CircuitName);

    //TODO: Move FileNameOpts setup into separate function
    FileNameOpts->CircuitName = Options->CircuitName;
    FileNameOpts->ArchFile = Options->ArchFile;
    FileNameOpts->BlifFile = Options->BlifFile;
    FileNameOpts->NetFile = Options->NetFile;
    FileNameOpts->PlaceFile = Options->PlaceFile;
    FileNameOpts->RouteFile = Options->RouteFile;
    FileNameOpts->ActFile = Options->ActFile;
    FileNameOpts->PowerFile = Options->PowerFile;
    FileNameOpts->CmosTechFile = Options->CmosTechFile;
    FileNameOpts->out_file_prefix = Options->out_file_prefix;

    FileNameOpts->verify_file_digests = Options->verify_file_digests;

    SetupNetlistOpts(*Options, *NetlistOpts);
    SetupPlacerOpts(*Options, PlacerOpts);
    SetupAnnealSched(*Options, AnnealSched);
    SetupRouterOpts(*Options, RouterOpts);
    SetupAnalysisOpts(*Options, *AnalysisOpts);
    SetupPowerOpts(*Options, PowerOpts, Arch);

    if (readArchFile == true) {
        vtr::ScopedStartFinishTimer t("Loading Architecture Description");
        XmlReadArch(Options->ArchFile.value().c_str(),
                    TimingEnabled,
                    Arch,
                    device_ctx.physical_tile_types,
                    device_ctx.logical_block_types);
    }

    *user_models = Arch->models;
    *library_models = Arch->model_library;

    /* TODO: this is inelegant, I should be populating this information in XmlReadArch */
    device_ctx.EMPTY_TYPE = nullptr;
    for (const auto& type : device_ctx.physical_tile_types) {
        if (strcmp(type.name, EMPTY_BLOCK_NAME) == 0) {
            VTR_ASSERT(device_ctx.EMPTY_TYPE == nullptr);
            device_ctx.EMPTY_TYPE = &type;
        } else {
            if (block_type_contains_blif_model(logical_block_type(&type), MODEL_INPUT)) {
                device_ctx.input_types.insert(&type);
            }
            if (block_type_contains_blif_model(logical_block_type(&type), MODEL_OUTPUT)) {
                device_ctx.output_types.insert(&type);
            }
        }
    }

    VTR_ASSERT(device_ctx.EMPTY_TYPE != nullptr);

    if (device_ctx.input_types.empty()) {
        VPR_ERROR(VPR_ERROR_ARCH,
                  "Architecture contains no top-level block type containing '.input' models");
    }

    if (device_ctx.output_types.empty()) {
        VPR_ERROR(VPR_ERROR_ARCH,
                  "Architecture contains no top-level block type containing '.output' models");
    }

    Segments = Arch->Segments;

    SetupSwitches(*Arch, RoutingArch, Arch->Switches, Arch->num_switches);
    SetupRoutingArch(*Arch, RoutingArch);
    SetupTiming(*Options, TimingEnabled, Timing);
    SetupPackerOpts(*Options, PackerOpts);
    RoutingArch->write_rr_graph_filename = Options->write_rr_graph_file;
    RoutingArch->read_rr_graph_filename = Options->read_rr_graph_file;

    //Setup the default flow, if no specific stages specified
    //do all
    if (!Options->do_packing
        && !Options->do_placement
        && !Options->do_routing
        && !Options->do_analysis) {
        //run all stages if none specified
        PackerOpts->doPacking = STAGE_DO;
        PlacerOpts->doPlacement = STAGE_DO;
        RouterOpts->doRouting = STAGE_DO;
        AnalysisOpts->doAnalysis = STAGE_AUTO; //Deferred until implementation status known
    } else {
        //We run all stages up to the specified stage
        //Note that by checking in reverse order (i.e. analysis to packing)
        //we ensure that earlier stages override the default 'LOAD' action
        //set by later stages

        if (Options->do_analysis) {
            PackerOpts->doPacking = STAGE_LOAD;
            PlacerOpts->doPlacement = STAGE_LOAD;
            RouterOpts->doRouting = STAGE_LOAD;
            AnalysisOpts->doAnalysis = STAGE_DO;
        }

        if (Options->do_routing) {
            PackerOpts->doPacking = STAGE_LOAD;
            PlacerOpts->doPlacement = STAGE_LOAD;
            RouterOpts->doRouting = STAGE_DO;
            AnalysisOpts->doAnalysis = ((Options->do_analysis) ? STAGE_DO : STAGE_AUTO); //Always run analysis after routing
        }

        if (Options->do_placement) {
            PackerOpts->doPacking = STAGE_LOAD;
            PlacerOpts->doPlacement = STAGE_DO;
        }

        if (Options->do_packing) {
            PackerOpts->doPacking = STAGE_DO;
        }
    }

    /* init global variables */
    vtr::out_file_prefix = Options->out_file_prefix;

    /* Set seed for pseudo-random placement, default seed to 1 */
    PlacerOpts->seed = Options->Seed;
    vtr::srandom(PlacerOpts->seed);

    {
        vtr::ScopedStartFinishTimer t("Building complex block graph");
        alloc_and_load_all_pb_graphs(PowerOpts->do_power);
        *PackerRRGraphs = alloc_and_load_all_lb_type_rr_graph();
    }

    if ((Options->clock_modeling == ROUTED_CLOCK) || (Options->clock_modeling == DEDICATED_NETWORK)) {
        ClockModeling::treat_clock_pins_as_non_globals();
    }

    if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_LB_TYPE_RR_GRAPH)) {
        echo_lb_type_rr_graphs(getEchoFileName(E_ECHO_LB_TYPE_RR_GRAPH), *PackerRRGraphs);
    }

    if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_PB_GRAPH)) {
        echo_pb_graph(getEchoFileName(E_ECHO_PB_GRAPH));
    }

    *GraphPause = Options->GraphPause;

    *ShowGraphics = Options->show_graphics;

    *SaveGraphics = Options->save_graphics;

    if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_ARCH)) {
        EchoArch(getEchoFileName(E_ECHO_ARCH), device_ctx.physical_tile_types, device_ctx.logical_block_types, Arch);
    }
}

static void SetupTiming(const t_options& Options, const bool TimingEnabled, t_timing_inf* Timing) {
    /* Don't do anything if they don't want timing */
    if (false == TimingEnabled) {
        Timing->timing_analysis_enabled = false;
        return;
    }

    Timing->timing_analysis_enabled = TimingEnabled;
    Timing->SDCFile = Options.SDCFile;
}

/* This loads up VPR's arch_switch_inf data by combining the switches from
 * the arch file with the special switches that VPR needs. */
static void SetupSwitches(const t_arch& Arch,
                          t_det_routing_arch* RoutingArch,
                          const t_arch_switch_inf* ArchSwitches,
                          int NumArchSwitches) {
    auto& device_ctx = g_vpr_ctx.mutable_device();

    int switches_to_copy = NumArchSwitches;
    device_ctx.num_arch_switches = NumArchSwitches;

    RoutingArch->wire_to_arch_ipin_switch = find_ipin_cblock_switch_index(Arch);

    /* Depends on device_ctx.num_arch_switches */
    RoutingArch->delayless_switch = device_ctx.num_arch_switches++;

    /* Alloc the list now that we know the final num_arch_switches value */
    device_ctx.arch_switch_inf = new t_arch_switch_inf[device_ctx.num_arch_switches];
    for (int iswitch = 0; iswitch < switches_to_copy; iswitch++) {
        device_ctx.arch_switch_inf[iswitch] = ArchSwitches[iswitch];
    }

    /* Delayless switch for connecting sinks and sources with their pins. */
    device_ctx.arch_switch_inf[RoutingArch->delayless_switch].set_type(SwitchType::MUX);
    device_ctx.arch_switch_inf[RoutingArch->delayless_switch].name = vtr::strdup("__vpr_delayless_switch__");
    device_ctx.arch_switch_inf[RoutingArch->delayless_switch].R = 0.;
    device_ctx.arch_switch_inf[RoutingArch->delayless_switch].Cin = 0.;
    device_ctx.arch_switch_inf[RoutingArch->delayless_switch].Cout = 0.;
    device_ctx.arch_switch_inf[RoutingArch->delayless_switch].set_Tdel(t_arch_switch_inf::UNDEFINED_FANIN, 0.);
    device_ctx.arch_switch_inf[RoutingArch->delayless_switch].power_buffer_type = POWER_BUFFER_TYPE_NONE;
    device_ctx.arch_switch_inf[RoutingArch->delayless_switch].mux_trans_size = 0.;
    device_ctx.arch_switch_inf[RoutingArch->delayless_switch].buf_size_type = BufferSize::ABSOLUTE;
    device_ctx.arch_switch_inf[RoutingArch->delayless_switch].buf_size = 0.;
    VTR_ASSERT_MSG(device_ctx.arch_switch_inf[RoutingArch->delayless_switch].buffered(), "Delayless switch expected to be buffered (isolating)");
    VTR_ASSERT_MSG(device_ctx.arch_switch_inf[RoutingArch->delayless_switch].configurable(), "Delayless switch expected to be configurable");

    RoutingArch->global_route_switch = RoutingArch->delayless_switch;

    //Warn about non-zero Cout values for the ipin switch, since these values have no effect.
    //VPR do not model the R/C's of block internal routing connectsion.
    //
    //Note that we don't warn about the R value as it may be used to size the buffer (if buf_size_type is AUTO)
    if (device_ctx.arch_switch_inf[RoutingArch->wire_to_arch_ipin_switch].Cout != 0.) {
        VTR_LOG_WARN("Non-zero switch output capacitance (%g) has no effect when switch '%s' is used for connection block inputs\n",
                     device_ctx.arch_switch_inf[RoutingArch->wire_to_arch_ipin_switch].Cout, Arch.ipin_cblock_switch_name.c_str());
    }
}

/* Sets up routing structures. Since checks are already done, this
 * just copies values across */
static void SetupRoutingArch(const t_arch& Arch,
                             t_det_routing_arch* RoutingArch) {
    RoutingArch->switch_block_type = Arch.SBType;
    RoutingArch->R_minW_nmos = Arch.R_minW_nmos;
    RoutingArch->R_minW_pmos = Arch.R_minW_pmos;
    RoutingArch->Fs = Arch.Fs;
    RoutingArch->directionality = BI_DIRECTIONAL;
    if (Arch.Segments.size()) {
        RoutingArch->directionality = Arch.Segments[0].directionality;
    }

    /* copy over the switch block information */
    RoutingArch->switchblocks = Arch.switchblocks;
}

static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts) {
    RouterOpts->astar_fac = Options.astar_fac;
    RouterOpts->bb_factor = Options.bb_factor;
    RouterOpts->criticality_exp = Options.criticality_exp;
    RouterOpts->max_criticality = Options.max_criticality;
    RouterOpts->max_router_iterations = Options.max_router_iterations;
    RouterOpts->init_wirelength_abort_threshold = Options.router_init_wirelength_abort_threshold;
    RouterOpts->min_incremental_reroute_fanout = Options.min_incremental_reroute_fanout;
    RouterOpts->incr_reroute_delay_ripup = Options.incr_reroute_delay_ripup;
    RouterOpts->pres_fac_mult = Options.pres_fac_mult;
    RouterOpts->route_type = Options.RouteType;

    RouterOpts->full_stats = Options.full_stats;

    //TODO document these?
    RouterOpts->congestion_analysis = Options.full_stats;
    RouterOpts->fanout_analysis = Options.full_stats;
    RouterOpts->switch_usage_analysis = Options.full_stats;

    RouterOpts->verify_binary_search = Options.verify_binary_search;
    RouterOpts->router_algorithm = Options.RouterAlgorithm;
    RouterOpts->fixed_channel_width = Options.RouteChanWidth;
    RouterOpts->min_channel_width_hint = Options.min_route_chan_width_hint;

    //TODO document these?
    RouterOpts->trim_empty_channels = false; /* DEFAULT */
    RouterOpts->trim_obs_channels = false;   /* DEFAULT */

    RouterOpts->initial_pres_fac = Options.initial_pres_fac;
    RouterOpts->base_cost_type = Options.base_cost_type;
    RouterOpts->first_iter_pres_fac = Options.first_iter_pres_fac;
    RouterOpts->acc_fac = Options.acc_fac;
    RouterOpts->bend_cost = Options.bend_cost;
    if (Options.do_routing) {
        RouterOpts->doRouting = STAGE_DO;
    }
    RouterOpts->routing_failure_predictor = Options.routing_failure_predictor;
    RouterOpts->routing_budgets_algorithm = Options.routing_budgets_algorithm;
    RouterOpts->save_routing_per_iteration = Options.save_routing_per_iteration;
    RouterOpts->congested_routing_iteration_threshold_frac = Options.congested_routing_iteration_threshold_frac;
    RouterOpts->route_bb_update = Options.route_bb_update;
    RouterOpts->clock_modeling = Options.clock_modeling;
    RouterOpts->high_fanout_threshold = Options.router_high_fanout_threshold;
    RouterOpts->router_debug_net = Options.router_debug_net;
    RouterOpts->router_debug_sink_rr = Options.router_debug_sink_rr;
    RouterOpts->lookahead_type = Options.router_lookahead_type;
    RouterOpts->max_convergence_count = Options.router_max_convergence_count;
    RouterOpts->reconvergence_cpd_threshold = Options.router_reconvergence_cpd_threshold;
    RouterOpts->first_iteration_timing_report_file = Options.router_first_iteration_timing_report_file;

    RouterOpts->strict_checks = Options.strict_checks;

    RouterOpts->write_router_lookahead = Options.write_router_lookahead;
    RouterOpts->read_router_lookahead = Options.read_router_lookahead;
}

static void SetupAnnealSched(const t_options& Options,
                             t_annealing_sched* AnnealSched) {
    AnnealSched->alpha_t = Options.PlaceAlphaT;
    if (AnnealSched->alpha_t >= 1 || AnnealSched->alpha_t <= 0) {
        VPR_FATAL_ERROR(VPR_ERROR_OTHER, "alpha_t must be between 0 and 1 exclusive.\n");
    }

    AnnealSched->exit_t = Options.PlaceExitT;
    if (AnnealSched->exit_t <= 0) {
        VPR_FATAL_ERROR(VPR_ERROR_OTHER, "exit_t must be greater than 0.\n");
    }

    AnnealSched->init_t = Options.PlaceInitT;
    if (AnnealSched->init_t <= 0) {
        VPR_FATAL_ERROR(VPR_ERROR_OTHER, "init_t must be greater than 0.\n");
    }

    if (AnnealSched->init_t < AnnealSched->exit_t) {
        VPR_FATAL_ERROR(VPR_ERROR_OTHER, "init_t must be greater or equal to than exit_t.\n");
    }

    AnnealSched->inner_num = Options.PlaceInnerNum;
    if (AnnealSched->inner_num <= 0) {
        VPR_FATAL_ERROR(VPR_ERROR_OTHER, "inner_num must be greater than 0.\n");
    }

    AnnealSched->type = Options.anneal_sched_type;
}

/* Sets up the s_packer_opts structure baesd on users inputs and on the architecture specified.
 * Error checking, such as checking for conflicting params is assumed to be done beforehand
 */
void SetupPackerOpts(const t_options& Options,
                     t_packer_opts* PackerOpts) {
    PackerOpts->output_file = Options.NetFile;

    PackerOpts->blif_file_name = Options.BlifFile;

    if (Options.do_packing) {
        PackerOpts->doPacking = STAGE_DO;
    }

    //TODO: document?
    PackerOpts->global_clocks = true;       /* DEFAULT */
    PackerOpts->hill_climbing_flag = false; /* DEFAULT */

    PackerOpts->allow_unrelated_clustering = Options.allow_unrelated_clustering;
    PackerOpts->connection_driven = Options.connection_driven_clustering;
    PackerOpts->timing_driven = Options.timing_driven_clustering;
    PackerOpts->cluster_seed_type = Options.cluster_seed_type;
    PackerOpts->alpha = Options.alpha_clustering;
    PackerOpts->beta = Options.beta_clustering;
    PackerOpts->pack_verbosity = Options.pack_verbosity;
    PackerOpts->enable_pin_feasibility_filter = Options.enable_clustering_pin_feasibility_filter;
    PackerOpts->balance_block_type_utilization = Options.balance_block_type_utilization;
    PackerOpts->target_external_pin_util = Options.target_external_pin_util;
    PackerOpts->target_device_utilization = Options.target_device_utilization;
    PackerOpts->prioritize_transitive_connectivity = Options.pack_prioritize_transitive_connectivity;
    PackerOpts->high_fanout_threshold = Options.pack_high_fanout_threshold;
    PackerOpts->transitive_fanout_threshold = Options.pack_transitive_fanout_threshold;
    PackerOpts->feasible_block_array_size = Options.pack_feasible_block_array_size;

    //TODO: document?
    PackerOpts->inter_cluster_net_delay = 1.0; /* DEFAULT */
    PackerOpts->auto_compute_inter_cluster_net_delay = true;
    PackerOpts->packer_algorithm = PACK_GREEDY; /* DEFAULT */

    PackerOpts->device_layout = Options.device_layout;
}

static void SetupNetlistOpts(const t_options& Options, t_netlist_opts& NetlistOpts) {
    NetlistOpts.const_gen_inference = Options.const_gen_inference;
    NetlistOpts.absorb_buffer_luts = Options.absorb_buffer_luts;
    NetlistOpts.sweep_dangling_primary_ios = Options.sweep_dangling_primary_ios;
    NetlistOpts.sweep_dangling_nets = Options.sweep_dangling_nets;
    NetlistOpts.sweep_dangling_blocks = Options.sweep_dangling_blocks;
    NetlistOpts.sweep_constant_primary_outputs = Options.sweep_constant_primary_outputs;
    NetlistOpts.netlist_verbosity = Options.netlist_verbosity;
}

/* Sets up the s_placer_opts structure based on users input. Error checking,
 * such as checking for conflicting params is assumed to be done beforehand */
static void SetupPlacerOpts(const t_options& Options, t_placer_opts* PlacerOpts) {
    if (Options.do_placement) {
        PlacerOpts->doPlacement = STAGE_DO;
    }

    PlacerOpts->inner_loop_recompute_divider = Options.inner_loop_recompute_divider;

    //TODO: document?
    PlacerOpts->place_cost_exp = 1;

    PlacerOpts->td_place_exp_first = Options.place_exp_first;

    PlacerOpts->td_place_exp_last = Options.place_exp_last;

    PlacerOpts->place_algorithm = Options.PlaceAlgorithm;

    PlacerOpts->pad_loc_file = Options.pad_loc_file;
    PlacerOpts->pad_loc_type = Options.pad_loc_type;

    PlacerOpts->place_chan_width = Options.PlaceChanWidth;

    PlacerOpts->recompute_crit_iter = Options.RecomputeCritIter;

    PlacerOpts->timing_tradeoff = Options.PlaceTimingTradeoff;

    /* Depends on PlacerOpts->place_algorithm */
    PlacerOpts->enable_timing_computations = Options.ShowPlaceTiming;

    PlacerOpts->delay_offset = Options.place_delay_offset;
    PlacerOpts->delay_ramp_delta_threshold = Options.place_delay_ramp_delta_threshold;
    PlacerOpts->delay_ramp_slope = Options.place_delay_ramp_slope;
    PlacerOpts->tsu_rel_margin = Options.place_tsu_rel_margin;
    PlacerOpts->tsu_abs_margin = Options.place_tsu_abs_margin;
    PlacerOpts->delay_model_type = Options.place_delay_model;
    PlacerOpts->delay_model_reducer = Options.place_delay_model_reducer;

    //TODO: document?
    PlacerOpts->place_freq = PLACE_ONCE; /* DEFAULT */

    PlacerOpts->post_place_timing_report_file = Options.post_place_timing_report_file;

    PlacerOpts->rlim_escape_fraction = Options.place_rlim_escape_fraction;
    PlacerOpts->move_stats_file = Options.place_move_stats_file;

    PlacerOpts->strict_checks = Options.strict_checks;

    PlacerOpts->write_placement_delay_lookup = Options.write_placement_delay_lookup;
    PlacerOpts->read_placement_delay_lookup = Options.read_placement_delay_lookup;

    PlacerOpts->allowed_tiles_for_delay_model = Options.allowed_tiles_for_delay_model;
}

static void SetupAnalysisOpts(const t_options& Options, t_analysis_opts& analysis_opts) {
    if (Options.do_analysis) {
        analysis_opts.doAnalysis = STAGE_DO;
    }

    analysis_opts.gen_post_synthesis_netlist = Options.Generate_Post_Synthesis_Netlist;

    analysis_opts.timing_report_npaths = Options.timing_report_npaths;
    analysis_opts.timing_report_detail = Options.timing_report_detail;
    analysis_opts.timing_report_skew = Options.timing_report_skew;
}

static void SetupPowerOpts(const t_options& Options, t_power_opts* power_opts, t_arch* Arch) {
    auto& device_ctx = g_vpr_ctx.mutable_device();

    power_opts->do_power = Options.do_power;

    if (power_opts->do_power) {
        if (!Arch->power)
            Arch->power = (t_power_arch*)vtr::malloc(sizeof(t_power_arch));
        if (!Arch->clocks)
            Arch->clocks = (t_clock_arch*)vtr::malloc(sizeof(t_clock_arch));
        device_ctx.clock_arch = Arch->clocks;
    } else {
        Arch->power = nullptr;
        Arch->clocks = nullptr;
        device_ctx.clock_arch = nullptr;
    }
}

static int find_ipin_cblock_switch_index(const t_arch& Arch) {
    int ipin_cblock_switch_index = UNDEFINED;
    for (int i = 0; i < Arch.num_switches; ++i) {
        if (Arch.Switches[i].name == Arch.ipin_cblock_switch_name) {
            if (ipin_cblock_switch_index != UNDEFINED) {
                VPR_FATAL_ERROR(VPR_ERROR_ARCH, "Found duplicate switches named '%s'\n", Arch.ipin_cblock_switch_name.c_str());
            } else {
                ipin_cblock_switch_index = i;
            }
        }
    }

    if (ipin_cblock_switch_index == UNDEFINED) {
        VPR_FATAL_ERROR(VPR_ERROR_ARCH, "Failed to find connection block input pin switch named '%s'\n", Arch.ipin_cblock_switch_name.c_str());
    }
    return ipin_cblock_switch_index;
}
