#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<std::unique_ptr<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.emplace_back(new xc7series::ConfigurationPacket(
	    0, xc7series::ConfigurationPacket::NOP,
	    xc7series::ConfigurationRegister::CRC, word_span));
}

void AddType1(
    std::vector<std::unique_ptr<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.emplace_back(
	    new xc7series::ConfigurationPacket(*(packet.second)));
}

// Empty
void AddType1E(
    std::vector<std::unique_ptr<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.emplace_back(
	    new xc7series::ConfigurationPacket(*(packet.second)));
}

void AddType2(
    std::vector<std::unique_ptr<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.emplace_back(
		    new xc7series::ConfigurationPacket(*(packet1_pair.second)));
		packet1 = packets[0].get();
	}
	// 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.emplace_back(
		    new xc7series::ConfigurationPacket(*(packet.second)));
	}
}

// Empty packets should produce just the header
TEST(BitstreamWriterTest, WriteHeader) {
	std::vector<std::unique_ptr<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<std::unique_ptr<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<std::unique_ptr<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<std::unique_ptr<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<std::unique_ptr<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);
}
