/*
 * Takes in a collection of ConfigurationPacket and writes them to specified
 * file This includes the following: -Bus auto detection -Sync Word -FPGA
 * configuration
 */
#ifndef PRJXRAY_LIB_XILINX_BITSTREAM_WRITER_H
#define PRJXRAY_LIB_XILINX_BITSTREAM_WRITER_H

#include <algorithm>
#include <fstream>
#include <memory>
#include <vector>

#include <absl/strings/str_cat.h>
#include <absl/time/clock.h>
#include <absl/time/time.h>
#include <absl/types/optional.h>
#include <absl/types/span.h>

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

namespace prjxray {
namespace xilinx {

uint32_t packet2header(
    const ConfigurationPacket<Series7ConfigurationRegister>& packet);
uint32_t packet2header(
    const ConfigurationPacket<Spartan6ConfigurationRegister>& packet);
// Writes out the complete Xilinx bitstream including
// header, sync word and configuration sequence.
template <typename ArchType>
class BitstreamWriter {
       public:
	typedef std::vector<uint32_t> header_t;
	typedef std::vector<std::unique_ptr<
	    ConfigurationPacket<typename ArchType::ConfRegType>>>
	    packets_t;
	typedef std::vector<uint8_t> BitstreamHeader;
	// Only defined if a packet exists
	typedef absl::optional<absl::Span<const uint32_t>> op_data_t;
	typedef absl::Span<const uint32_t>::iterator data_iterator_t;
	using itr_value_type = uint32_t;

	class packet_iterator
	    : public std::iterator<std::input_iterator_tag, itr_value_type> {
	       public:
		packet_iterator& operator++();

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

		const itr_value_type operator*() const;
		const itr_value_type operator->() const;

		typedef enum {
			STATE_HEADER = 1,
			STATE_DATA = 2,
			STATE_END = 3,
		} state_t;

	       protected:
		explicit packet_iterator(
		    const ConfigurationPacket<typename ArchType::ConfRegType>*
		        packet,
		    state_t state,
		    data_iterator_t itr_data);

	       private:
		friend iterator;
		friend BitstreamWriter;

		// Data iterators
		// First over the fixed header, then the configuration data
		state_t state_;
		// Over packet.data()
		data_iterator_t itr_data_;

		const ConfigurationPacket<typename ArchType::ConfRegType>*
		    packet_;
	};

	class iterator
	    : public std::iterator<std::input_iterator_tag, itr_value_type> {
	       public:
		iterator& operator++();

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

		const itr_value_type operator*() const;
		const itr_value_type operator->() const;

		packet_iterator packet_begin();
		packet_iterator packet_end();

	       protected:
		explicit iterator(
		    header_t::iterator itr_header,
		    const packets_t& packets,
		    typename packets_t::const_iterator itr_packets,
		    absl::optional<packet_iterator> op_itr_packet);

	       private:
		friend BitstreamWriter;
		// Data iterators
		// First over the fixed header, then the configuration data
		header_t::iterator itr_header_;
		const packets_t& packets_;
		typename packets_t::const_iterator itr_packets_;
		absl::optional<packet_iterator> op_itr_packet_;
	};

	BitstreamWriter(const packets_t& packets) : packets_(packets) {}

	// Writes out the complete bitstream for Xilinx FPGA based on
	// the Configuration Package which holds the complete programming
	// sequence.
	int writeBitstream(
	    const typename ArchType::ConfigurationPackage& packets,
	    const std::string& part_name,
	    const std::string& frames_file,
	    const std::string& generator_name,
	    const std::string& output_file);
	iterator begin();
	iterator end();

       private:
	static header_t header_;
	const packets_t& packets_;

	// Creates a Xilinx bit header which is mostly a
	// Tag-Length-Value(TLV) format documented here:
	// http://www.fpga-faq.com/FAQ_Pages/0026_Tell_me_about_bit_files.htm
	BitstreamHeader create_header(const std::string& part_name,
	                              const std::string& frames_file_name,
	                              const std::string& generator_name);
};

template <typename ArchType>
int BitstreamWriter<ArchType>::writeBitstream(
    const typename ArchType::ConfigurationPackage& packets,
    const std::string& part_name,
    const std::string& frames_file,
    const std::string& generator_name,
    const std::string& output_file) {
	std::ofstream out_file(output_file, std::ofstream::binary);
	if (!out_file) {
		std::cerr << "Unable to open file for writting: " << output_file
		          << std::endl;
		return 1;
	}

	BitstreamHeader bit_header(
	    create_header(part_name, frames_file, generator_name));
	out_file.write(reinterpret_cast<const char*>(bit_header.data()),
	               bit_header.size());

	auto end_of_header_pos = out_file.tellp();
	auto header_data_length_pos =
	    end_of_header_pos - static_cast<std::ofstream::off_type>(4);

	BitstreamWriter<ArchType> out_bitstream_writer(packets);
	int bytes_per_word = sizeof(typename ArchType::WordType);
	for (uint32_t word : out_bitstream_writer) {
		for (int byte = bytes_per_word - 1; byte >= 0; byte--) {
			out_file.put((word >> (byte * 8)) & 0xFF);
		}
	}

	uint32_t length_of_data = out_file.tellp() - end_of_header_pos;

	out_file.seekp(header_data_length_pos);
	for (int byte = 3; byte >= 0; byte--) {
		out_file.put((length_of_data >> (byte * 8)) & 0xFF);
	}
	return 0;
}

template <typename ArchType>
typename BitstreamWriter<ArchType>::BitstreamHeader
BitstreamWriter<ArchType>::create_header(const std::string& part_name,
                                         const std::string& frames_file_name,
                                         const std::string& generator_name) {
	// Sync header
	BitstreamHeader bit_header{0x0,  0x9,  0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
	                           0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01, 'a'};
	auto build_source =
	    absl::StrCat(frames_file_name, ";Generator=" + generator_name);
	bit_header.push_back(
	    static_cast<uint8_t>((build_source.size() + 1) >> 8));
	bit_header.push_back(static_cast<uint8_t>(build_source.size() + 1));
	bit_header.insert(bit_header.end(), build_source.begin(),
	                  build_source.end());
	bit_header.push_back(0x0);

	// Source file.
	bit_header.push_back('b');
	bit_header.push_back(static_cast<uint8_t>((part_name.size() + 1) >> 8));
	bit_header.push_back(static_cast<uint8_t>(part_name.size() + 1));
	bit_header.insert(bit_header.end(), part_name.begin(), part_name.end());
	bit_header.push_back(0x0);

	// Build timestamp.
	auto build_time = absl::Now();
	auto build_date_string =
	    absl::FormatTime("%E4Y/%m/%d", build_time, absl::UTCTimeZone());
	auto build_time_string =
	    absl::FormatTime("%H:%M:%S", build_time, absl::UTCTimeZone());

	bit_header.push_back('c');
	bit_header.push_back(
	    static_cast<uint8_t>((build_date_string.size() + 1) >> 8));
	bit_header.push_back(
	    static_cast<uint8_t>(build_date_string.size() + 1));
	bit_header.insert(bit_header.end(), build_date_string.begin(),
	                  build_date_string.end());
	bit_header.push_back(0x0);

	bit_header.push_back('d');
	bit_header.push_back(
	    static_cast<uint8_t>((build_time_string.size() + 1) >> 8));
	bit_header.push_back(
	    static_cast<uint8_t>(build_time_string.size() + 1));
	bit_header.insert(bit_header.end(), build_time_string.begin(),
	                  build_time_string.end());
	bit_header.push_back(0x0);
	bit_header.insert(bit_header.end(), {'e', 0x0, 0x0, 0x0, 0x0});
	return bit_header;
}

template <typename ArchType>
typename BitstreamWriter<ArchType>::packet_iterator
BitstreamWriter<ArchType>::iterator::packet_begin() {
	// itr_packets = packets.begin();
	const ConfigurationPacket<typename ArchType::ConfRegType>& packet =
	    **itr_packets_;

	return BitstreamWriter::packet_iterator(
	    &packet, BitstreamWriter::packet_iterator::STATE_HEADER,
	    packet.data().begin());
}

template <typename ArchType>
typename BitstreamWriter<ArchType>::packet_iterator
BitstreamWriter<ArchType>::iterator::packet_end() {
	const ConfigurationPacket<typename ArchType::ConfRegType>& packet =
	    **itr_packets_;

	return BitstreamWriter<ArchType>::packet_iterator(
	    &packet, BitstreamWriter::packet_iterator::STATE_END,
	    // Essentially ignored
	    packet.data().end());
}

template <typename ArchType>
BitstreamWriter<ArchType>::packet_iterator::packet_iterator(
    const ConfigurationPacket<typename ArchType::ConfRegType>* packet,
    state_t state,
    data_iterator_t itr_data)
    : state_(state), itr_data_(itr_data), packet_(packet) {}

template <typename ArchType>
typename BitstreamWriter<ArchType>::packet_iterator&
    BitstreamWriter<ArchType>::packet_iterator::operator++() {
	if (state_ == STATE_HEADER) {
		itr_data_ = packet_->data().begin();
		if (itr_data_ == packet_->data().end()) {
			state_ = STATE_END;
		} else {
			state_ = STATE_DATA;
		}
	} else if (state_ == STATE_DATA) {
		/// Advance. data must be valid while not at end
		itr_data_++;
		// Reached this end of this packet?
		if (itr_data_ == packet_->data().end()) {
			state_ = STATE_END;
		}
	}
	return *this;
}

template <typename ArchType>
bool BitstreamWriter<ArchType>::packet_iterator::operator==(
    const packet_iterator& other) const {
	return state_ == other.state_ && itr_data_ == other.itr_data_;
}

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

template <typename ArchType>
const typename BitstreamWriter<ArchType>::itr_value_type
    BitstreamWriter<ArchType>::packet_iterator::operator*() const {
	if (state_ == STATE_HEADER) {
		return packet2header(*packet_);
	} else if (state_ == STATE_DATA) {
		return *itr_data_;
	}
	return 0;  // XXX: assert or something?
}

template <typename ArchType>
const typename BitstreamWriter<ArchType>::itr_value_type
    BitstreamWriter<ArchType>::packet_iterator::operator->() const {
	return *(*this);
}

/**************************************************
 * BitstreamWriter::iterator
 *************************************************/

template <typename ArchType>
typename BitstreamWriter<ArchType>::iterator
BitstreamWriter<ArchType>::begin() {
	typename packets_t::const_iterator itr_packets = packets_.begin();
	absl::optional<packet_iterator> op_packet_itr;

	// May have no packets
	if (itr_packets != packets_.end()) {
		// op_packet_itr = packet_begin();
		// FIXME: de-duplicate this
		const ConfigurationPacket<typename ArchType::ConfRegType>&
		    packet = **itr_packets;
		packet_iterator packet_itr =
		    packet_iterator(&packet, packet_iterator::STATE_HEADER,
		                    packet.data().begin());
		op_packet_itr = packet_itr;
	}
	return iterator(header_.begin(), packets_, itr_packets, op_packet_itr);
}

template <typename ArchType>
typename BitstreamWriter<ArchType>::iterator BitstreamWriter<ArchType>::end() {
	return iterator(header_.end(), packets_, packets_.end(),
	                absl::optional<packet_iterator>());
}

template <typename ArchType>
BitstreamWriter<ArchType>::iterator::iterator(
    header_t::iterator itr_header,
    const typename BitstreamWriter<ArchType>::packets_t& packets,
    typename BitstreamWriter<ArchType>::packets_t::const_iterator itr_packets,
    absl::optional<packet_iterator> itr_packet)
    : itr_header_(itr_header),
      packets_(packets),
      itr_packets_(itr_packets),
      op_itr_packet_(itr_packet) {}

template <typename ArchType>
typename BitstreamWriter<ArchType>::iterator&
    BitstreamWriter<ArchType>::iterator::operator++() {
	// Still generating header?
	if (itr_header_ != header_.end()) {
		itr_header_++;
		// Finished header?
		// Will advance to initialized itr_packets value
		// XXX: maybe should just overwrite here
		if (itr_header_ == header_.end()) {
			itr_packets_ = packets_.begin();
			if (itr_packets_ != packets_.end()) {
				op_itr_packet_ = packet_begin();
			}
		}
		// Then somewhere in packets
	} else {
		// We are either at end() in which case this operation is
		// invalid Or there is a packet in progress packet in progress?
		// Advance it
		++(*op_itr_packet_);
		// Done with this packet?
		if (*op_itr_packet_ == packet_end()) {
			itr_packets_++;
			if (itr_packets_ == packets_.end()) {
				// we are at the very end
				// invalidate data to be neat
				op_itr_packet_.reset();
			} else {
				op_itr_packet_ = packet_begin();
			}
		}
	}
	return *this;
}

template <typename ArchType>
bool BitstreamWriter<ArchType>::iterator::operator==(
    const iterator& other) const {
	return itr_header_ == other.itr_header_ &&
	       itr_packets_ == other.itr_packets_ &&
	       op_itr_packet_ == other.op_itr_packet_;
}

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

template <typename ArchType>
const typename BitstreamWriter<ArchType>::itr_value_type
    BitstreamWriter<ArchType>::iterator::operator*() const {
	if (itr_header_ != header_.end()) {
		return *itr_header_;
	} else {
		// Iterating over packets, get data from current packet position
		return *(*op_itr_packet_);
	}
}

template <typename ArchType>
const typename BitstreamWriter<ArchType>::itr_value_type
    BitstreamWriter<ArchType>::iterator::operator->() const {
	return *(*this);
}

}  // namespace xilinx
}  // namespace prjxray

#endif  // PRJXRAY_LIB_XILINX_XC7SERIES_BITSTREAM_WRITER_H
