#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

#include <absl/strings/str_cat.h>
#include <absl/strings/str_split.h>
#include <absl/time/clock.h>
#include <absl/time/time.h>
#include <gflags/gflags.h>
#include <prjxray/memory_mapped_file.h>
#include <prjxray/xilinx/xc7series/bitstream_reader.h>
#include <prjxray/xilinx/xc7series/bitstream_writer.h>
#include <prjxray/xilinx/xc7series/command.h>
#include <prjxray/xilinx/xc7series/configuration.h>
#include <prjxray/xilinx/xc7series/configuration_options_0_value.h>
#include <prjxray/xilinx/xc7series/configuration_packet_with_payload.h>
#include <prjxray/xilinx/xc7series/ecc.h>
#include <prjxray/xilinx/xc7series/nop_packet.h>
#include <prjxray/xilinx/xc7series/part.h>

DEFINE_string(part_name, "", "");
DEFINE_string(part_file, "", "Definition file for target 7-series part");
DEFINE_string(bitstream_file,
              "",
              "Initial bitstream to which the deltas are applied.");
DEFINE_string(
    frm_file,
    "",
    "File containing a list of frame deltas to be applied to the base "
    "bitstream.  Each line in the file is of the form: "
    "<frame_address> <word1>,...,<word101>.");
DEFINE_string(output_file, "", "Write patched bitsteam to file");

namespace xc7series = prjxray::xilinx::xc7series;

int main(int argc, char* argv[]) {
	gflags::SetUsageMessage(argv[0]);
	gflags::ParseCommandLineFlags(&argc, &argv, true);

	auto part = xc7series::Part::FromFile(FLAGS_part_file);
	if (!part) {
		std::cerr << "Part file not found or invalid" << std::endl;
		return 1;
	}

	auto bitstream_file =
	    prjxray::MemoryMappedFile::InitWithFile(FLAGS_bitstream_file);
	if (!bitstream_file) {
		std::cerr << "Can't open base bitstream file: "
		          << FLAGS_bitstream_file << std::endl;
		return 1;
	}

	auto bitstream_reader = xc7series::BitstreamReader::InitWithBytes(
	    bitstream_file->as_bytes());
	if (!bitstream_reader) {
		std::cout
		    << "Bitstream does not appear to be a 7-series bitstream!"
		    << std::endl;
		return 1;
	}

	auto bitstream_config =
	    xc7series::Configuration::InitWithPackets(*part, *bitstream_reader);
	if (!bitstream_config) {
		std::cerr << "Bitstream does not appear to be for this part"
		          << std::endl;
		return 1;
	}

	// Copy the base frames to a mutable collection
	std::map<xc7series::FrameAddress, std::vector<uint32_t>> frames;
	for (auto& frame_val : bitstream_config->frames()) {
		auto& cur_frame = frames[frame_val.first];

		std::copy(frame_val.second.begin(), frame_val.second.end(),
		          std::back_inserter(cur_frame));
	}

	// Apply the deltas.
	std::ifstream frm_file(FLAGS_frm_file);
	if (!frm_file) {
		std::cerr << "Unable to open frm file: " << FLAGS_frm_file
		          << std::endl;
		return 1;
	}

	std::string frm_line;
	while (std::getline(frm_file, frm_line)) {
		if (frm_line[0] == '#')
			continue;

		std::pair<std::string, std::string> frame_delta =
		    absl::StrSplit(frm_line, ' ');

		uint32_t frame_address =
		    std::stoul(frame_delta.first, nullptr, 16);

		auto& frame_data = frames[frame_address];
		frame_data.resize(101);

		std::vector<std::string> frame_data_strings =
		    absl::StrSplit(frame_delta.second, ',');
		if (frame_data_strings.size() != 101) {
			std::cerr << "Frame " << std::hex << frame_address
			          << ": found " << std::dec
			          << frame_data_strings.size()
			          << "words instead of 101";
			continue;
		};

		std::transform(frame_data_strings.begin(),
		               frame_data_strings.end(), frame_data.begin(),
		               [](const std::string& val) -> uint32_t {
			               return std::stoul(val, nullptr, 16);
		               });

		uint32_t ecc = 0;
		for (size_t ii = 0; ii < frame_data.size(); ++ii) {
			ecc = xc7series::icap_ecc(ii, frame_data[ii], ecc);
		}

		// Replace the old ECC with the new.
		frame_data[0x32] &= 0xFFFFE000;
		frame_data[0x32] |= (ecc & 0x1FFF);
	}

	std::vector<std::unique_ptr<xc7series::ConfigurationPacket>>
	    out_packets;

	// Generate a single type 2 packet that writes everything at once.
	std::vector<uint32_t> packet_data;
	for (auto& frame : frames) {
		std::copy(frame.second.begin(), frame.second.end(),
		          std::back_inserter(packet_data));

		auto next_address = part->GetNextFrameAddress(frame.first);
		if (next_address &&
		    (next_address->block_type() != frame.first.block_type() ||
		     next_address->is_bottom_half_rows() !=
		         frame.first.is_bottom_half_rows() ||
		     next_address->row() != frame.first.row())) {
			packet_data.insert(packet_data.end(), 202, 0);
		}
	}
	packet_data.insert(packet_data.end(), 202, 0);

	// Initialization sequence
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::TIMER, {0x0}));
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::WBSTAR, {0x0}));
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CMD,
	        {static_cast<uint32_t>(xc7series::Command::NOP)}));
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CMD,
	        {static_cast<uint32_t>(xc7series::Command::RCRC)}));
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::UNKNOWN, {0x0}));

	// Configuration Options 0
	out_packets.emplace_back(new xc7series::ConfigurationPacketWithPayload<
	                         1>(
	    xc7series::ConfigurationPacket::Opcode::Write,
	    xc7series::ConfigurationRegister::COR0,
	    {xc7series::ConfigurationOptions0Value()
	         .SetAddPipelineStageForDoneIn(true)
	         .SetReleaseDonePinAtStartupCycle(
	             xc7series::ConfigurationOptions0Value::SignalReleaseCycle::
	                 Phase4)
	         .SetStallAtStartupCycleUntilDciMatch(
	             xc7series::ConfigurationOptions0Value::StallCycle::NoWait)
	         .SetStallAtStartupCycleUntilMmcmLock(
	             xc7series::ConfigurationOptions0Value::StallCycle::NoWait)
	         .SetReleaseGtsSignalAtStartupCycle(
	             xc7series::ConfigurationOptions0Value::SignalReleaseCycle::
	                 Phase5)
	         .SetReleaseGweSignalAtStartupCycle(
	             xc7series::ConfigurationOptions0Value::SignalReleaseCycle::
	                 Phase6)}));

	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::COR1, {0x0}));
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::IDCODE, {part->idcode()}));
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CMD,
	        {static_cast<uint32_t>(xc7series::Command::SWITCH)}));
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::MASK, {0x401}));
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CTL0, {0x501}));
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::MASK, {0x0}));
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CTL1, {0x0}));
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::FAR, {0x0}));
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CMD,
	        {static_cast<uint32_t>(xc7series::Command::WCFG)}));
	out_packets.emplace_back(new xc7series::NopPacket());

	// Frame data write
	out_packets.emplace_back(new xc7series::ConfigurationPacket(
	    1, xc7series::ConfigurationPacket::Opcode::Write,
	    xc7series::ConfigurationRegister::FDRI, {}));
	out_packets.emplace_back(new xc7series::ConfigurationPacket(
	    2, xc7series::ConfigurationPacket::Opcode::Write,
	    xc7series::ConfigurationRegister::FDRI, packet_data));

	// Finalization sequence
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CMD,
	        {static_cast<uint32_t>(xc7series::Command::RCRC)}));
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CMD,
	        {static_cast<uint32_t>(xc7series::Command::GRESTORE)}));
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CMD,
	        {static_cast<uint32_t>(xc7series::Command::LFRM)}));
	for (int ii = 0; ii < 100; ++ii) {
		out_packets.emplace_back(new xc7series::NopPacket());
	}
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CMD,
	        {static_cast<uint32_t>(xc7series::Command::START)}));
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::FAR, {0x3be0000}));
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::MASK, {0x501}));
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CTL0, {0x501}));
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CMD,
	        {static_cast<uint32_t>(xc7series::Command::RCRC)}));
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(new xc7series::NopPacket());
	out_packets.emplace_back(
	    new xc7series::ConfigurationPacketWithPayload<1>(
	        xc7series::ConfigurationPacket::Opcode::Write,
	        xc7series::ConfigurationRegister::CMD,
	        {static_cast<uint32_t>(xc7series::Command::DESYNC)}));
	for (int ii = 0; ii < 400; ++ii) {
		out_packets.emplace_back(new xc7series::NopPacket());
	}

	// Write bitstream.
	xc7series::BitstreamWriter out_bitstream_writer(out_packets);
	std::ofstream out_file(FLAGS_output_file);
	if (!out_file) {
		std::cerr << "Unable to open file for writting: "
		          << FLAGS_output_file << std::endl;
		return 1;
	}

	// Xilinx BIT header.
	// Sync header
	std::vector<uint8_t> bit_header{0x0,  0x9,  0x0f, 0xf0, 0x0f,
	                                0xf0, 0x0f, 0xf0, 0x0f, 0xf0,
	                                0x00, 0x00, 0x01, 'a'};
	auto build_source = absl::StrCat(FLAGS_frm_file, ";Generator=xc7patch");
	bit_header.push_back(
	    static_cast<uint8_t>((build_source.size() + 1) >> 8));
	bit_header.push_back(static_cast<uint8_t>(build_source.size() + 1));
	bit_header.insert(bit_header.end(), build_source.begin(),
	                  build_source.end());
	bit_header.push_back(0x0);

	// Source file.
	bit_header.push_back('b');
	bit_header.push_back(
	    static_cast<uint8_t>((FLAGS_part_name.size() + 1) >> 8));
	bit_header.push_back(static_cast<uint8_t>(FLAGS_part_name.size() + 1));
	bit_header.insert(bit_header.end(), FLAGS_part_name.begin(),
	                  FLAGS_part_name.end());
	bit_header.push_back(0x0);

	// Build timestamp.
	auto build_time = absl::Now();
	auto build_date_string =
	    absl::FormatTime("%E4Y/%m/%d", build_time, absl::UTCTimeZone());
	auto build_time_string =
	    absl::FormatTime("%H:%M:%S", build_time, absl::UTCTimeZone());

	bit_header.push_back('c');
	bit_header.push_back(
	    static_cast<uint8_t>((build_date_string.size() + 1) >> 8));
	bit_header.push_back(
	    static_cast<uint8_t>(build_date_string.size() + 1));
	bit_header.insert(bit_header.end(), build_date_string.begin(),
	                  build_date_string.end());
	bit_header.push_back(0x0);

	bit_header.push_back('d');
	bit_header.push_back(
	    static_cast<uint8_t>((build_time_string.size() + 1) >> 8));
	bit_header.push_back(
	    static_cast<uint8_t>(build_time_string.size() + 1));
	bit_header.insert(bit_header.end(), build_time_string.begin(),
	                  build_time_string.end());
	bit_header.push_back(0x0);

	bit_header.insert(bit_header.end(), {'e', 0x0, 0x0, 0x0, 0x0});
	out_file.write(reinterpret_cast<const char*>(bit_header.data()),
	               bit_header.size());

	auto end_of_header_pos = out_file.tellp();
	auto header_data_length_pos =
	    end_of_header_pos - static_cast<std::ofstream::off_type>(4);

	for (uint32_t word : out_bitstream_writer) {
		out_file.put((word >> 24) & 0xFF);
		out_file.put((word >> 16) & 0xFF);
		out_file.put((word >> 8) & 0xFF);
		out_file.put((word)&0xFF);
	}

	uint32_t length_of_data = out_file.tellp() - end_of_header_pos;

	out_file.seekp(header_data_length_pos);
	out_file.put((length_of_data >> 24) & 0xFF);
	out_file.put((length_of_data >> 16) & 0xFF);
	out_file.put((length_of_data >> 8) & 0xFF);
	out_file.put((length_of_data)&0xFF);

	return 0;
}
