#include <array>

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

#include <prjxray/bit_ops.h>

using namespace prjxray::xilinx;

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(BitstreamWriter<Series7> 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<ConfigurationPacket<Series7::ConfRegType>>>&
        packets) {
	// InitWithWords doesn't like type 0
	/*
	static std::vector<uint32_t> words{0x00000000};
	absl::Span<uint32_t> word_span(words);
	auto packet =
	ConfigurationPacket<Series7::ConfRegType>::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 ConfigurationPacket<Series7::ConfRegType>(
	    0, ConfigurationPacket<Series7::ConfRegType>::NOP,
	    Series7::ConfRegType::CRC, word_span));
}

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

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

void AddType2(
    std::vector<std::unique_ptr<ConfigurationPacket<Series7::ConfRegType>>>&
        packets) {
	// Type 1 packet with address
	// Without this InitWithWords will fail on type 2
	ConfigurationPacket<Series7::ConfRegType>* packet1;
	{
		static std::vector<uint32_t> words{MakeType1(0x2, 0x3, 0)};
		absl::Span<uint32_t> word_span(words);
		auto packet1_pair =
		    ConfigurationPacket<Series7::ConfRegType>::InitWithWords(
		        word_span);
		packets.emplace_back(
		    new ConfigurationPacket<Series7::ConfRegType>(
		        *(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 =
		    ConfigurationPacket<Series7::ConfRegType>::InitWithWords(
		        word_span, packet1);
		packets.emplace_back(
		    new ConfigurationPacket<Series7::ConfRegType>(
		        *(packet.second)));
	}
}

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

	BitstreamWriter<Series7> 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, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
	    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000000BB, 0x11220044,
	    0xFFFFFFFF, 0xFFFFFFFF, 0xAA995566};
	EXPECT_EQ(words, ref_header);

	// dump_packets(writer);
}

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

TEST(BitstreamWriterTest, WriteType2) {
	std::vector<std::unique_ptr<ConfigurationPacket<Series7::ConfRegType>>>
	    packets;
	AddType2(packets);
	BitstreamWriter<Series7> writer(packets);
	// dump_packets(writer, false);
	std::vector<uint32_t> words(writer.begin(), writer.end());
	std::vector<uint32_t> ref{
	    // Bus width + sync
	    0x0FFFFFFFF, 0x0FFFFFFFF, 0x0FFFFFFFF, 0x0FFFFFFFF, 0x0FFFFFFFF,
	    0x0FFFFFFFF, 0x0FFFFFFFF, 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<ConfigurationPacket<Series7::ConfRegType>>>
	    packets;
	AddType1(packets);
	AddType1E(packets);
	AddType2(packets);
	AddType1E(packets);
	BitstreamWriter<Series7> writer(packets);
	// dump_packets(writer, false);
	std::vector<uint32_t> words(writer.begin(), writer.end());
	std::vector<uint32_t> ref{
	    // Bus width + sync
	    0x0FFFFFFFF, 0x0FFFFFFFF, 0x0FFFFFFFF, 0x0FFFFFFFF, 0x0FFFFFFFF,
	    0x0FFFFFFFF, 0x0FFFFFFFF, 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);
}
