#include <cstdio>
#include <cstring>
#include <fstream>

#include "vtr_assert.h"
#include "vtr_util.h"
#include "vtr_log.h"
#include "vtr_digest.h"

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

#include "globals.h"
#include "hash.h"
#include "read_place.h"
#include "read_xml_arch_file.h"

void read_place(const char* net_file,
                const char* place_file,
                bool verify_file_digests,
                const DeviceGrid& grid) {
    std::ifstream fstream(place_file);
    if (!fstream) {
        vpr_throw(VPR_ERROR_PLACE_F, __FILE__, __LINE__,
                        "'%s' - Cannot open place file.\n",
                        place_file);
    }

    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& place_ctx = g_vpr_ctx.mutable_placement();

    std::string line;
    int lineno = 0;
    bool seen_netlist_id = false;
    bool seen_grid_dimensions = false;
    while (std::getline(fstream, line)) { //Parse line-by-line
        ++lineno;

        std::vector<std::string> tokens = vtr::split(line);

        if (tokens.empty()) {
            continue; //Skip blank lines

        } else if (tokens[0][0] == '#') {
            continue; //Skip commented lines

        } else if (tokens.size() == 4
                   && tokens[0] == "Netlist_File:"
                   && tokens[2] == "Netlist_ID:") {
            //Check that the netlist used to generate this placement matches the one loaded
            //
            //NOTE: this is an optional check which causes no errors if this line is missing.
            //      This ensures other tools can still generate placement files which can be loaded
            //      by VPR.

            if (seen_netlist_id) {
                vpr_throw(VPR_ERROR_PLACE_F, place_file, lineno,
                          "Duplicate Netlist_File/Netlist_ID specification");
            }

            std::string place_netlist_id = tokens[3];
            std::string place_netlist_file = tokens[1];

            if (place_netlist_id != cluster_ctx.clb_nlist.netlist_id().c_str()) {
                auto msg = vtr::string_fmt("The packed netlist file that generated placement (File: '%s' ID: '%s')"
                                           " does not match current netlist (File: '%s' ID: '%s')",
                                           place_netlist_file.c_str(), place_netlist_id.c_str(),
                                           net_file, cluster_ctx.clb_nlist.netlist_id().c_str());
                if (verify_file_digests) {
                    vpr_throw(VPR_ERROR_PLACE_F, place_file, lineno, msg.c_str());
                } else {
                    vtr::printf_warning(place_file, lineno, "%s\n", msg.c_str());
                }
            }

            seen_netlist_id = true;

        } else if (tokens.size() == 7
                   && tokens[0] == "Array"
                   && tokens[1] == "size:"
                   && tokens[3] == "x"
                   && tokens[5] == "logic"
                   && tokens[6] == "blocks") {
            //Load the device grid dimensions

            if (seen_grid_dimensions) {
                vpr_throw(VPR_ERROR_PLACE_F, place_file, lineno,
                          "Duplicate device grid dimensions specification");
            }

            size_t place_file_width = vtr::atou(tokens[2]);
            size_t place_file_height = vtr::atou(tokens[4]);
            if (grid.width() != place_file_width || grid.height() != place_file_height) {
                vpr_throw(VPR_ERROR_PLACE_F, place_file, lineno,
                        "Current FPGA size (%d x %d) is different from size when placement generated (%d x %d)",
                        grid.width(), grid.height(), place_file_width, place_file_height);
            }

            seen_grid_dimensions = true;

        } else if (tokens.size() == 4 || (tokens.size() == 5 && tokens[4][0] == '#')) {
            //Load the block location
            //
            //We should have 4 tokens of actual data, with an optional 5th (commented) token indicating VPR's
            //internal block number

            //Grid dimensions are required by this point
            if (!seen_grid_dimensions) {
                vpr_throw(VPR_ERROR_PLACE_F, place_file, lineno,
                        "Missing device grid size specification");
            }

            std::string block_name = tokens[0];
            int block_x = vtr::atoi(tokens[1]);
            int block_y = vtr::atoi(tokens[2]);
            int block_z = vtr::atoi(tokens[3]);

			ClusterBlockId blk_id = cluster_ctx.clb_nlist.find_block(block_name);

            if (place_ctx.block_locs.size() != cluster_ctx.clb_nlist.blocks().size()) {
                //Resize if needed
                place_ctx.block_locs.resize(cluster_ctx.clb_nlist.blocks().size());
            }

            //Set the location
            place_ctx.block_locs[blk_id].x = block_x;
            place_ctx.block_locs[blk_id].y = block_y;
            place_ctx.block_locs[blk_id].z = block_z;

        } else {
            //Unrecognized
            vpr_throw(VPR_ERROR_PLACE_F, place_file, lineno,
                      "Invalid line '%s' in placement file",
                      line.c_str());
        }
    }

    place_ctx.placement_id = vtr::secure_digest_file(place_file);
}

void read_user_pad_loc(const char *pad_loc_file) {

	/* Reads in the locations of the IO pads from a file. */

	t_hash **hash_table, *h_ptr;
	int xtmp, ytmp;
	FILE *fp;
	char buf[vtr::bufsize], bname[vtr::bufsize], *ptr;

    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& device_ctx = g_vpr_ctx.device();
    auto& place_ctx = g_vpr_ctx.mutable_placement();

	vtr::printf_info("\n");
	vtr::printf_info("Reading locations of IO pads from '%s'.\n", pad_loc_file);
	fp = fopen(pad_loc_file, "r");
	if (!fp) vpr_throw(VPR_ERROR_PLACE_F, __FILE__, __LINE__,
				"'%s' - Cannot find IO pads location file.\n",
				pad_loc_file);

	hash_table = alloc_hash_table();
	for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
		if (is_io_type(cluster_ctx.clb_nlist.block_type(blk_id))) {
			insert_in_hash_table(hash_table, cluster_ctx.clb_nlist.block_name(blk_id).c_str(), size_t(blk_id));
			place_ctx.block_locs[blk_id].x = OPEN; /* Mark as not seen yet. */
		}
	}

	for (size_t i = 0; i < device_ctx.grid.width(); i++) {
		for (size_t j = 0; j < device_ctx.grid.height(); j++) {
            auto type = device_ctx.grid[i][j].type;
			if (is_io_type(type)) {
				for (int k = 0; k < type->capacity; k++) {
					if (place_ctx.grid_blocks[i][j].blocks[k] != INVALID_BLOCK_ID) {
						place_ctx.grid_blocks[i][j].blocks[k] = EMPTY_BLOCK_ID; /* Flag for err. check */
					}
				}
			}
		}
	}

	ptr = vtr::fgets(buf, vtr::bufsize, fp);

	while (ptr != nullptr) {
		ptr = vtr::strtok(buf, TOKENS, fp, buf);
		if (ptr == nullptr) {
			ptr = vtr::fgets(buf, vtr::bufsize, fp);
			continue; /* Skip blank or comment lines. */
		}

        if(strlen(ptr) + 1 < vtr::bufsize) {
            strcpy(bname, ptr);
        } else {
			vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, vtr::get_file_line_number_of_last_opened_file(),
					"Block name exceeded buffer size of %zu characters", vtr::bufsize);
        }

		ptr = vtr::strtok(nullptr, TOKENS, fp, buf);
		if (ptr == nullptr) {
			vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, vtr::get_file_line_number_of_last_opened_file(),
					"Incomplete.\n");
		}
		sscanf(ptr, "%d", &xtmp);

		ptr = vtr::strtok(nullptr, TOKENS, fp, buf);
		if (ptr == nullptr) {
			vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, vtr::get_file_line_number_of_last_opened_file(),
					"Incomplete.\n");
		}
		sscanf(ptr, "%d", &ytmp);

		ptr = vtr::strtok(nullptr, TOKENS, fp, buf);
		if (ptr == nullptr) {
			vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, vtr::get_file_line_number_of_last_opened_file(),
					"Incomplete.\n");
		}
        int k;
		sscanf(ptr, "%d", &k);

		ptr = vtr::strtok(nullptr, TOKENS, fp, buf);
		if (ptr != nullptr) {
			vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, vtr::get_file_line_number_of_last_opened_file(),
					"Extra characters at end of line.\n");
		}

		h_ptr = get_hash_entry(hash_table, bname);
		if (h_ptr == nullptr) {
			vtr::printf_warning(__FILE__, __LINE__,
					"[Line %d] Block %s invalid, no such IO pad.\n", vtr::get_file_line_number_of_last_opened_file(), bname);
			ptr = vtr::fgets(buf, vtr::bufsize, fp);
			continue;
		}
		ClusterBlockId bnum(h_ptr->index);
		int i = xtmp;
		int j = ytmp;

		if (place_ctx.block_locs[bnum].x != OPEN) {
			vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, vtr::get_file_line_number_of_last_opened_file(),
					"Block %s is listed twice in pad file.\n", bname);
		}

		if (i < 0 || i > int(device_ctx.grid.width() - 1) || j < 0 || j > int(device_ctx.grid.height() - 1)) {
			vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, 0,
					"Block #%zu (%s) location, (%d,%d) is out of range.\n", size_t(bnum), bname, i, j);
		}

        place_ctx.block_locs[bnum].x = i; /* Will be reloaded by initial_placement anyway. */
        place_ctx.block_locs[bnum].y = j; /* We need to set .x only as a done flag.         */
        place_ctx.block_locs[bnum].z = k;
        place_ctx.block_locs[bnum].is_fixed = true;

        auto type = device_ctx.grid[i][j].type;
		if (!is_io_type(type)) {
			vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, 0,
					"Attempt to place IO block %s at illegal location (%d, %d).\n", bname, i, j);
		}

		if (k >= type->capacity || k < 0) {
			vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, vtr::get_file_line_number_of_last_opened_file(),
					"Block %s subblock number (%d) is out of range.\n", bname, k);
		}
		place_ctx.grid_blocks[i][j].blocks[k] = bnum;
		place_ctx.grid_blocks[i][j].usage++;

		ptr = vtr::fgets(buf, vtr::bufsize, fp);
	}

	for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
        auto type = cluster_ctx.clb_nlist.block_type(blk_id);
		if (is_io_type(type) && place_ctx.block_locs[blk_id].x == OPEN) {
			vpr_throw(VPR_ERROR_PLACE_F, pad_loc_file, 0,
					"IO block %s location was not specified in the pad file.\n", cluster_ctx.clb_nlist.block_name(blk_id).c_str());
		}
	}

	fclose(fp);
	free_hash_table(hash_table);
	vtr::printf_info("Successfully read %s.\n", pad_loc_file);
	vtr::printf_info("\n");
}

/* Prints out the placement of the circuit. The architecture and    *
* netlist files used to generate this placement are recorded in the *
* file to avoid loading a placement with the wrong support files    *
* later.                                                            */
void print_place(const char* net_file,
                 const char* net_id,
                 const char* place_file) {
	FILE *fp;

    auto& device_ctx = g_vpr_ctx.device();
    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& place_ctx = g_vpr_ctx.mutable_placement();

	fp = fopen(place_file, "w");

	fprintf(fp, "Netlist_File: %s Netlist_ID: %s\n",
            net_file,
            net_id);
	fprintf(fp, "Array size: %zu x %zu logic blocks\n\n", device_ctx.grid.width(), device_ctx.grid.height());
	fprintf(fp, "#block name\tx\ty\tsubblk\tblock number\n");
	fprintf(fp, "#----------\t--\t--\t------\t------------\n");

	for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
		fprintf(fp, "%s\t", cluster_ctx.clb_nlist.block_name(blk_id).c_str());
		if (strlen(cluster_ctx.clb_nlist.block_name(blk_id).c_str()) < 8)
			fprintf(fp, "\t");

		fprintf(fp, "%d\t%d\t%d", place_ctx.block_locs[blk_id].x, place_ctx.block_locs[blk_id].y, place_ctx.block_locs[blk_id].z);
		fprintf(fp, "\t#%zu\n", size_t(blk_id));
	}
	fclose(fp);

    //Calculate the ID of the placement
    place_ctx.placement_id = vtr::secure_digest_file(place_file);
}
