#include "header.h"
#include <algorithm>
#include <ctime>
#include <sstream>

Header::Header(const std::string& line,
               std::vector<uint32_t>& fpga_config_packets) {
	absl::string_view header_str(line);
	// Go to tag 'a' of the TLV formatted header
	header_str.remove_prefix(header_str.find("61"));
	bool tlv_header_end = false;
	while (!tlv_header_end) {
		char tag = char(GetByteAndAdvance(header_str));
		switch (tag) {
			case 'a':
				design_name_ = GetTLVHeaderValue(header_str);
				break;
			case 'b':
				part_ = GetTLVHeaderValue(header_str);
				break;
			case 'c':
				date_ = GetTLVHeaderValue(header_str);
				break;
			case 'd':
				date_ += " " + GetTLVHeaderValue(header_str);
				break;
			case 'e':
				// Get number of bytes in bitstream and multiply
				// by 8 to obtain number of bits
				no_bits_ = GetWord(header_str) * 8;
				tlv_header_end = true;
				break;
			default:
				assert(false);
		}
	}
	while (!header_str.empty()) {
		fpga_config_packets.emplace_back(GetWord(header_str));
	}
}

std::string Header::GetDate() {
	int year, month, day, hour, min, sec;
	std::replace_if(date_.begin(), date_.end(),
	    		[](char c) { return c == '/' or c == ':'; }, ' ');
	std::istringstream(date_) >> year >> month >> day >> hour >> min >> sec;
	std::tm time_raw = {sec, min, hour, day, month - 1, year - 1900};
	time_t time = mktime(&time_raw);
	const std::tm* time_out = std::localtime(&time);
	return std::string(std::asctime(time_out));
}

std::string Header::GetArchitecture() {
	if (part_.find("xczu") != std::string::npos) {
		return "zynquplus";
	}
	if (part_.find("7a") != std::string::npos) {
		return "artix7";
	}
	if (part_.find("xcku") != std::string::npos) {
		return "kintexu";
	}
	return "Unknown architecture";
}

void Header::Write(std::ostream& out) {
	out << "Xilinx ASCII Bitstream" << std::endl;
	out << "Created by" << std::endl;
	out << "Design name:   " << design_name_ << std::endl;
	out << "Architecture:  " << GetArchitecture() << std::endl;
	out << "Part:          " << part_ << std::endl;
	out << "Date:          " << GetDate();
	out << "Bits:          " << no_bits_ << std::endl;
}

size_t Header::GetByteAndAdvance(absl::string_view& str_view) {
	size_t space_pos(str_view.find(" "));
	size_t byte =
	    std::stoul(std::string(str_view.substr(0, space_pos)), nullptr, 16);
	str_view.remove_prefix((space_pos != absl::string_view::npos)
	                           ? space_pos + 1
	                           : str_view.size());
	return byte;
}

size_t Header::GetTLVHeaderLength(absl::string_view& str_view) {
	return (GetByteAndAdvance(str_view) << 8) | GetByteAndAdvance(str_view);
}

std::string Header::GetTLVHeaderValue(absl::string_view& str_view) {
	size_t length(GetTLVHeaderLength(str_view));
	std::string value;
	for (size_t i = 0; i < length; i++) {
		value += char(GetByteAndAdvance(str_view));
	}
	// Lose trailing 0x00
	value.pop_back();
	return value;
}

uint32_t Header::GetWord(absl::string_view& str_view) {
	return (GetByteAndAdvance(str_view) << 24) |
	       (GetByteAndAdvance(str_view) << 16) |
	       (GetByteAndAdvance(str_view) << 8) | GetByteAndAdvance(str_view);
}
