#include <array>

#include <gtest/gtest.h>
#include <prjxray/xilinx/xc7series/bitstream_reader.h>
#include <prjxray/xilinx/xc7series/bitstream_writer.h>
#include <prjxray/xilinx/xc7series/configuration_packet.h>
#include <prjxray/xilinx/xc7series/configuration_register.h>

#include <prjxray/bit_ops.h>

namespace xc7series = prjxray::xilinx::xc7series;

constexpr uint32_t kType1NOP = prjxray::bit_field_set<uint32_t>(0, 31, 29, 0x1);

constexpr uint32_t MakeType1(const int opcode,
                             const int address,
                             const int word_count) {
	return prjxray::bit_field_set<uint32_t>(
	    prjxray::bit_field_set<uint32_t>(
	        prjxray::bit_field_set<uint32_t>(
	            prjxray::bit_field_set<uint32_t>(0x0, 31, 29, 0x1), 28, 27,
	            opcode),
	        26, 13, address),
	    10, 0, word_count);
}

constexpr uint32_t MakeType2(const int opcode, const int word_count) {
	return prjxray::bit_field_set<uint32_t>(
	    prjxray::bit_field_set<uint32_t>(
	        prjxray::bit_field_set<uint32_t>(0x0, 31, 29, 0x2), 28, 27,
	        opcode),
	    26, 0, word_count);
}

void dump_packets(xc7series::BitstreamWriter writer, bool nl = true) {
	int i = 0;
	// for (uint32_t x : itr) {
	for (auto itr = writer.begin(); itr != writer.end(); ++itr) {
		if (nl) {
			printf("% 3d: 0x0%08X\n", i, *itr);
		} else {
			printf("0x0%08X, ", *itr);
		}
		fflush(stdout);
		++i;
	}
	if (!nl) {
		printf("\n");
	}
}

// Special all 0's
void AddType0(std::vector<xc7series::ConfigurationPacket>& packets) {
	// InitWithWords doesn't like type 0
	/*
	static std::vector<uint32_t> words{0x00000000};
	absl::Span<uint32_t> word_span(words);
	auto packet = xc7series::ConfigurationPacket::InitWithWords(word_span);
	packets.push_back(*(packet.second));
	*/
	static std::vector<uint32_t> words{};
	absl::Span<uint32_t> word_span(words);
	// CRC is config value 0
	packets.push_back(xc7series::ConfigurationPacket(
	    0, xc7series::ConfigurationPacket::NOP,
	    xc7series::ConfigurationRegister::CRC, word_span));
}

void AddType1(std::vector<xc7series::ConfigurationPacket>& packets) {
	static std::vector<uint32_t> words{MakeType1(0x2, 0x3, 2), 0xAA, 0xBB};
	absl::Span<uint32_t> word_span(words);
	auto packet = xc7series::ConfigurationPacket::InitWithWords(word_span);
	packets.push_back(*(packet.second));
}

// Empty
void AddType1E(std::vector<xc7series::ConfigurationPacket>& packets) {
	static std::vector<uint32_t> words{MakeType1(0x2, 0x3, 0)};
	absl::Span<uint32_t> word_span(words);
	auto packet = xc7series::ConfigurationPacket::InitWithWords(word_span);
	packets.push_back(*(packet.second));
}

void AddType2(std::vector<xc7series::ConfigurationPacket>& packets) {
	// Type 1 packet with address
	// Without this InitWithWords will fail on type 2
	xc7series::ConfigurationPacket* packet1;
	{
		static std::vector<uint32_t> words{MakeType1(0x2, 0x3, 0)};
		absl::Span<uint32_t> word_span(words);
		auto packet1_pair =
		    xc7series::ConfigurationPacket::InitWithWords(word_span);
		packets.push_back(*(packet1_pair.second));
		packet1 = &packets[0];
	}
	// Type 2 packet with data
	{
		static std::vector<uint32_t> words{
		    MakeType2(0x01, 12), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
		absl::Span<uint32_t> word_span(words);
		auto packet = xc7series::ConfigurationPacket::InitWithWords(
		    word_span, packet1);
		packets.push_back(*(packet.second));
	}
}

// Empty packets should produce just the header
TEST(BitstreamWriterTest, WriteHeader) {
	std::vector<xc7series::ConfigurationPacket> packets;

	xc7series::BitstreamWriter writer(packets);
	std::vector<uint32_t> words(writer.begin(), writer.end());

	// Per UG470 pg 80: Bus Width Auto Detection
	std::vector<uint32_t> ref_header{0xFFFFFFFF, 0x000000BB, 0x11220044,
	                                 0xFFFFFFFF, 0xFFFFFFFF, 0xAA995566};
	EXPECT_EQ(words, ref_header);

	// dump_packets(writer);
}

TEST(BitstreamWriterTest, WriteType0) {
	std::vector<xc7series::ConfigurationPacket> packets;
	AddType0(packets);
	xc7series::BitstreamWriter writer(packets);
	// dump_packets(writer, false);
	std::vector<uint32_t> words(writer.begin(), writer.end());
	std::vector<uint32_t> ref{// Bus width + sync
	                          0x0FFFFFFFF, 0x0000000BB, 0x011220044,
	                          0x0FFFFFFFF, 0x0FFFFFFFF, 0x0AA995566,
	                          // Type 0
	                          0x00000000};
	EXPECT_EQ(words, ref);
}
TEST(BitstreamWriterTest, WriteType1) {
	std::vector<xc7series::ConfigurationPacket> packets;
	AddType1(packets);
	xc7series::BitstreamWriter writer(packets);
	// dump_packets(writer, false);
	std::vector<uint32_t> words(writer.begin(), writer.end());
	std::vector<uint32_t> ref{// Bus width + sync
	                          0x0FFFFFFFF, 0x0000000BB, 0x011220044,
	                          0x0FFFFFFFF, 0x0FFFFFFFF, 0x0AA995566,
	                          // Type 1
	                          0x030006002, 0x0000000AA, 0x0000000BB};
	EXPECT_EQ(words, ref);
}

TEST(BitstreamWriterTest, WriteType2) {
	std::vector<xc7series::ConfigurationPacket> packets;
	AddType2(packets);
	xc7series::BitstreamWriter writer(packets);
	// dump_packets(writer, false);
	std::vector<uint32_t> words(writer.begin(), writer.end());
	std::vector<uint32_t> ref{
	    // Bus width + sync
	    0x0FFFFFFFF, 0x0000000BB, 0x011220044, 0x0FFFFFFFF, 0x0FFFFFFFF,
	    0x0AA995566,
	    // Type 1 + type 2 header
	    0x030006000, 0x04800000C, 0x000000001, 0x000000002, 0x000000003,
	    0x000000004, 0x000000005, 0x000000006, 0x000000007, 0x000000008,
	    0x000000009, 0x00000000A, 0x00000000B, 0x00000000C};
	EXPECT_EQ(words, ref);
}

TEST(BitstreamWriterTest, WriteMulti) {
	std::vector<xc7series::ConfigurationPacket> packets;
	AddType1(packets);
	AddType1E(packets);
	AddType2(packets);
	AddType1E(packets);
	xc7series::BitstreamWriter writer(packets);
	// dump_packets(writer, false);
	std::vector<uint32_t> words(writer.begin(), writer.end());
	std::vector<uint32_t> ref{
	    // Bus width + sync
	    0x0FFFFFFFF, 0x0000000BB, 0x011220044, 0x0FFFFFFFF, 0x0FFFFFFFF,
	    0x0AA995566,
	    // Type1
	    0x030006002, 0x0000000AA, 0x0000000BB,
	    // Type1
	    0x030006000,
	    // Type 1 + type 2 header
	    0x030006000, 0x04800000C, 0x000000001, 0x000000002, 0x000000003,
	    0x000000004, 0x000000005, 0x000000006, 0x000000007, 0x000000008,
	    0x000000009, 0x00000000A, 0x00000000B, 0x00000000C,
	    // Type 1
	    0x030006000};
	EXPECT_EQ(words, ref);
}
