#ifndef PRJXRAY_LIB_XILINX_BITSTREAM_READER_H
#define PRJXRAY_LIB_XILINX_BITSTREAM_READER_H

#include <algorithm>
#include <iostream>
#include <memory>
#include <vector>

#include <absl/types/span.h>

#include <prjxray/big_endian_span.h>
#include <prjxray/xilinx/architectures.h>
#include <prjxray/xilinx/configuration_packet.h>

namespace prjxray {
namespace xilinx {

// Constructs a collection of 32-bit big-endian words from a bitstream file.
// Provides an iterator over the configuration packets.
template <typename ArchType>
class BitstreamReader {
       public:
	using value_type = ConfigurationPacket<typename ArchType::ConfRegType>;

	// Implements an iterator over the words grouped in configuration
	// packets.
	class iterator
	    : public std::iterator<std::input_iterator_tag, value_type> {
	       public:
		iterator& operator++();

		bool operator==(const iterator& other) const;
		bool operator!=(const iterator& other) const;

		const value_type& operator*() const;
		const value_type* operator->() const;

	       protected:
		explicit iterator(absl::Span<uint32_t> words);

	       private:
		friend BitstreamReader;

		typename value_type::ParseResult parse_result_;
		absl::Span<uint32_t> words_;
	};

	// Construct a reader from a collection of 32-bit, big-endian words.
	// Assumes that any sync word has already been removed.
	BitstreamReader(std::vector<uint32_t>&& words)
	    : words_(std::move(words)) {}

	BitstreamReader() {}
	size_t size() { return words_.size(); }

	// Construct a `BitstreamReader` from a Container of bytes.
	// Any bytes preceding an initial sync word are ignored.
	template <typename T>
	static absl::optional<BitstreamReader<ArchType>> InitWithBytes(
	    T bitstream);

	const std::vector<uint32_t>& words() { return words_; };

	// Returns an iterator that yields `ConfigurationPackets`
	// as read from the bitstream.
	iterator begin();
	iterator end();

       private:
	static std::array<uint8_t, 4> kSyncWord;

	std::vector<uint32_t> words_;
};

template <typename ArchType>
template <typename T>
absl::optional<BitstreamReader<ArchType>>
BitstreamReader<ArchType>::InitWithBytes(T bitstream) {
	// If this is really a Xilinx bitstream, there will be a sync
	// word somewhere toward the beginning.
	auto sync_pos = std::search(bitstream.begin(), bitstream.end(),
	                            kSyncWord.begin(), kSyncWord.end());
	if (sync_pos == bitstream.end()) {
		return absl::optional<BitstreamReader<ArchType>>();
	}
	sync_pos += kSyncWord.size();

	// Wrap the provided container in a span that strips off the preamble.
	absl::Span<typename T::value_type> bitstream_span(bitstream);
	auto config_packets =
	    bitstream_span.subspan(sync_pos - bitstream.begin());

	// Convert the bytes into 32-bit or 16-bit in case of Spartan6,
	// big-endian words.
	auto big_endian_reader =
	    make_big_endian_span<typename ArchType::WordType>(config_packets);
	std::vector<uint32_t> words{big_endian_reader.begin(),
	                            big_endian_reader.end()};

	return BitstreamReader<ArchType>(std::move(words));
}

// Sync word as specified in UG470 page 81
template <typename ArchType>
std::array<uint8_t, 4> BitstreamReader<ArchType>::kSyncWord{0xAA, 0x99, 0x55,
                                                            0x66};

template <typename ArchType>
typename BitstreamReader<ArchType>::iterator
BitstreamReader<ArchType>::begin() {
	return iterator(absl::MakeSpan(words_));
}

template <typename ArchType>
typename BitstreamReader<ArchType>::iterator BitstreamReader<ArchType>::end() {
	return iterator({});
}

template <typename ArchType>
BitstreamReader<ArchType>::iterator::iterator(absl::Span<uint32_t> words) {
	parse_result_.first = words;
	parse_result_.second = {};
	++(*this);
}

template <typename ArchType>
typename BitstreamReader<ArchType>::iterator&
    BitstreamReader<ArchType>::iterator::operator++() {
	do {
		auto new_result =
		    ConfigurationPacket<typename ArchType::ConfRegType>::
		        InitWithWords(parse_result_.first,
		                      parse_result_.second.has_value()
		                          ? parse_result_.second.operator->()
		                          : nullptr);

		// If the a valid header is being found but there are
		// insufficient words to yield a packet, consider it the end.
		if (new_result.first == parse_result_.first) {
			words_ = absl::Span<uint32_t>();
			break;
		}

		words_ = parse_result_.first;
		parse_result_ = new_result;
	} while (!parse_result_.first.empty() && !parse_result_.second);

	if (!parse_result_.second) {
		words_ = absl::Span<uint32_t>();
	}

	return *this;
}

template <typename ArchType>
bool BitstreamReader<ArchType>::iterator::operator==(
    const iterator& other) const {
	return words_ == other.words_;
}

template <typename ArchType>
bool BitstreamReader<ArchType>::iterator::operator!=(
    const iterator& other) const {
	return !(*this == other);
}

template <typename ArchType>
const typename BitstreamReader<ArchType>::value_type&
    BitstreamReader<ArchType>::iterator::operator*() const {
	return *(parse_result_.second);
}

template <typename ArchType>
const typename BitstreamReader<ArchType>::value_type*
    BitstreamReader<ArchType>::iterator::operator->() const {
	return parse_result_.second.operator->();
}
}  // namespace xilinx
}  // namespace prjxray

#endif  // PRJXRAY_LIB_XILINX_BITSTREAM_READER_H
