#include <cstdint>
#include <iostream>
#include <vector>

#include <absl/types/span.h>
#include <gtest/gtest.h>
#include <prjxray/memory_mapped_file.h>
#include <prjxray/xilinx/architectures.h>
#include <prjxray/xilinx/configuration.h>
#include <prjxray/xilinx/spartan6/frame_address.h>
#include <yaml-cpp/yaml.h>

using namespace prjxray::xilinx;

TEST(ConfigurationTest, ConstructFromPacketsWithSingleFrame) {
	std::vector<spartan6::FrameAddress> test_part_addresses;
	test_part_addresses.push_back(0x0A);
	test_part_addresses.push_back(0x0B);

	spartan6::Part test_part(0x1234, test_part_addresses);

	std::vector<uint32_t> idcode{0x1234};
	std::vector<uint32_t> cmd{0x0001};
	std::vector<uint32_t> frame_address{0x345};
	std::vector<uint32_t> frame(65, 0xAA);

	std::vector<ConfigurationPacket<typename Spartan6::ConfRegType>>
	    packets{
	        {
	            static_cast<unsigned int>(0x1),
	            ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
	            Spartan6::ConfRegType::IDCODE,
	            absl::MakeSpan(idcode),
	        },
	        {
	            static_cast<unsigned int>(0x1),
	            ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
	            Spartan6::ConfRegType::FAR_MIN,
	            absl::MakeSpan(frame_address),
	        },
	        {
	            static_cast<unsigned int>(0x1),
	            ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
	            Spartan6::ConfRegType::CMD,
	            absl::MakeSpan(cmd),
	        },
	        {
	            static_cast<unsigned int>(0x1),
	            ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
	            Spartan6::ConfRegType::FDRI,
	            absl::MakeSpan(frame),
	        },
	    };

	auto test_config =
	    Configuration<Spartan6>::InitWithPackets(test_part, packets);
	ASSERT_TRUE(test_config);

	EXPECT_EQ(test_config->part().idcode(), static_cast<uint32_t>(0x1234));
	EXPECT_EQ(test_config->frames().size(), static_cast<size_t>(1));
	EXPECT_EQ(test_config->frames().at(0x345), frame);
}

TEST(ConfigurationTest, ConstructFromPacketsWithAutoincrement) {
	std::vector<spartan6::FrameAddress> test_part_addresses;
	for (int ii = 0x310; ii < 0x320; ++ii) {
		test_part_addresses.push_back(ii);
	}

	for (int ii = 0x330; ii < 0x331; ++ii) {
		test_part_addresses.push_back(ii);
	}

	spartan6::Part test_part(0x1234, test_part_addresses);

	std::vector<uint32_t> idcode{0x1234};
	std::vector<uint32_t> cmd{0x0001};
	std::vector<uint32_t> frame_address{0x31f};
	std::vector<uint32_t> frame(65 * 2, 0xAA);
	std::fill_n(frame.begin() + 65, 65, 0xBB);

	std::vector<ConfigurationPacket<Spartan6::ConfRegType>> packets{
	    {
	        static_cast<unsigned int>(0x1),
	        ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
	        Spartan6::ConfRegType::IDCODE,
	        absl::MakeSpan(idcode),
	    },
	    {
	        static_cast<unsigned int>(0x1),
	        ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
	        Spartan6::ConfRegType::FAR_MIN,
	        absl::MakeSpan(frame_address),
	    },
	    {
	        static_cast<unsigned int>(0x1),
	        ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
	        Spartan6::ConfRegType::CMD,
	        absl::MakeSpan(cmd),
	    },
	    {
	        static_cast<unsigned int>(0x1),
	        ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
	        Spartan6::ConfRegType::FDRI,
	        absl::MakeSpan(frame),
	    },
	};

	auto test_config =
	    Configuration<Spartan6>::InitWithPackets(test_part, packets);
	ASSERT_TRUE(test_config);

	absl::Span<uint32_t> frame_span(frame);
	EXPECT_EQ(test_config->part().idcode(), static_cast<uint32_t>(0x1234));
	EXPECT_EQ(test_config->frames().size(), static_cast<size_t>(2));
	EXPECT_EQ(test_config->frames().at(0x31f),
	          std::vector<uint32_t>(65, 0xAA));
	// TODO This test fails with a C++ exception because the address
	// of next frame is 0x320 instead of 0x330 as defined in the test_part
	// EXPECT_EQ(test_config->frames().at(0x330),
	//          std::vector<uint32_t>(65, 0xBB));
}

TEST(ConfigurationTest, DISABLED_CheckForPaddingAfterIOBFrame) {
	std::vector<spartan6::FrameAddress> test_part_addresses = {
	    spartan6::FrameAddress(spartan6::BlockType::CLB_IOI_CLK, 0, 0, 0),
	    spartan6::FrameAddress(spartan6::BlockType::BLOCK_RAM, 1, 0, 0),
	    spartan6::FrameAddress(spartan6::BlockType::IOB, 2, 0, 0)};

	auto test_part = absl::optional<spartan6::Part>(
	    spartan6::Part(0x1234, test_part_addresses));

	Frames<Spartan6> frames;
	frames.getFrames().emplace(std::make_pair(
	    test_part_addresses.at(0), std::vector<uint32_t>(65, 0xAA)));
	frames.getFrames().emplace(std::make_pair(
	    test_part_addresses.at(1), std::vector<uint32_t>(65, 0xBB)));
	frames.getFrames().emplace(std::make_pair(
	    test_part_addresses.at(2), std::vector<uint32_t>(65, 0xCC)));
	ASSERT_EQ(frames.getFrames().size(), 3);

	Configuration<Spartan6>::PacketData packet_data =
	    Configuration<Spartan6>::createType2ConfigurationPacketData(
	        frames.getFrames(), test_part);
	// createType2ConfigurationPacketData should add a 16-bit pad word after
	// after the IOB frame
	EXPECT_EQ(packet_data.size(), 3 * 65 + 1);

	std::vector<uint32_t> idcode{0x1234};
	std::vector<uint32_t> cmd{0x0001};
	std::vector<uint32_t> frame_address{0x0};

	std::vector<ConfigurationPacket<Spartan6::ConfRegType>> packets{
	    {
	        static_cast<unsigned int>(0x1),
	        ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
	        Spartan6::ConfRegType::IDCODE,
	        absl::MakeSpan(idcode),
	    },
	    {
	        static_cast<unsigned int>(0x1),
	        ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
	        Spartan6::ConfRegType::FAR,
	        absl::MakeSpan(frame_address),
	    },
	    {
	        static_cast<unsigned int>(0x1),
	        ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
	        Spartan6::ConfRegType::CMD,
	        absl::MakeSpan(cmd),
	    },
	    {
	        static_cast<unsigned int>(0x1),
	        ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
	        Spartan6::ConfRegType::FDRI,
	        absl::MakeSpan(packet_data),
	    },
	};

	auto test_config =
	    Configuration<Spartan6>::InitWithPackets(*test_part, packets);
	ASSERT_EQ(test_config->frames().size(), 5);
	for (auto& frame : test_config->frames()) {
		EXPECT_EQ(frame.second, frames.getFrames().at(frame.first));
	}
}
