// Copyright 2020 Project U-Ray Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <vector>
#include <iostream>
#include <map>
#include <string>
#include <fstream>
#include <stdexcept>
#include <iterator>
#include <stdarg.h>
#include <iomanip>
#include "common.h"

const uint32_t preamble = 0xAA995566;

#define SKIP_CRC
#define SKIP_CHECKSUM
#define SKIP_COMMENT

class dummy_ostream : public std::ostream {

};

dummy_ostream dummy_out;

bool verbose_flag = false;

#define COMMENT(x) (verbose_flag ? std::cout : dummy_out) << x << std::endl


struct ByteStreamReader {
	std::vector<uint8_t> data;
	std::size_t ptr = 0;
	void reset() {
		ptr = 0;
	}
	bool done() {
		return ptr >= (data.size() - 3);
	}
	uint32_t curr_crc = 0;
	uint32_t curr_addr = 0;

	uint32_t next_u32(bool skip_crc = false) {
		if (done())
			throw std::runtime_error("at end of bitstream");
		uint32_t val = data[ptr] << 24UL | data[ptr+1] << 16UL | data[ptr+2] << 8UL | data[ptr+3];
		ptr += 4;
		if (!skip_crc)
			curr_crc = icap_crc(curr_addr, val, curr_crc);
		return val;
	}

	uint32_t peek_u32() {
		if (done())
			throw std::runtime_error("at end of bitstream");
		uint32_t val = data[ptr] << 24UL | data[ptr+1] << 16UL | data[ptr+2] << 8UL | data[ptr+3];
		return val;
	}
	void skip_till_preamble() {
		while (peek_u32() != preamble)
			++ptr;
		COMMENT("# found preamble at offset " << ptr);
		ptr += 4;
	}
};



enum BitstreamRegister : uint16_t {
	#define X(a, b) a = b,
	#include "registers.inc"
	#undef X
};



std::string get_register_name(uint16_t val) {
	BitstreamRegister r = (BitstreamRegister)val;
	#define X(a, b) if (val == a) return #a;
	#include "registers.inc"
	#undef X
	return stringf("reg%04x", val);
}

std::map<uint32_t, uint32_t> next_frame;

void parse_bitstream(ByteStreamReader &rd) {
	rd.reset();
	rd.skip_till_preamble();
	uint32_t frame = 0;
	uint16_t last_reg = 0;
	uint64_t checksum = 0, exp_checksum = 0;
	int word = 0;
	auto is_checksum = [] (int w, int b) {
		return ((w == 45 && b <= 31) || (w == 46 && b <= 15));
	};

	auto get_ecc_value = [](int word, int bit) {
		int nib = bit / 4;
		int nibbit = bit % 4;
		// ECC offset is expanded to 1 bit per nibble,
		// and then shifted based on the bit index in nibble
		// e.g. word 3, bit 9
		// offset: 0b10100110010 - concatenate (3 + (255 - 92)) [frame offset] and 9/4 [nibble offset]
		// becomes: 0x10100110010
		// shifted by bit in nibble (9%4): 0x20200220020 
		uint32_t offset =  (word + (255 - 92)) << 3  | nib;
		uint64_t exp_offset = 0;
		// Odd parity
		offset ^= (1 << 11);
		for (int i = 0; i < 11; i++)
			if (offset & (1 << i)) offset ^= (1 << 11);
		// Expansion
		for (int i = 0; i < 12; i++)
			if (offset & (1 << i)) exp_offset |= (1ULL << (4 * i));
		return exp_offset << nibbit;
	};

	auto process_word = [&](uint32_t data) {


		for (int i = 0; i < 32; i++)
			if (data & (1 << i)) {
				if (is_checksum(word, i)) {
					checksum |= 1ULL << ((word - 45) * 32 + i);
#ifdef SKIP_CHECKSUM
					continue;
#endif
				} else {
					exp_checksum ^= get_ecc_value(word, i);
				}
				std::cout <<  stringf("F0x%08xW%03dB%02d", frame, word, i) << std::endl;
			}			
		++word;
		if (word >= 93 && next_frame.count(frame)) {
			// 4 parity bits for each bit in nibbles
#if 0
			for (int i = 0; i < 4; i++)
				for (int j = 0; j < 11; j++)
					if (exp_checksum & (1ULL << (4 * j + i)))
						exp_checksum ^= (1ULL << (44 + i));
#endif
			COMMENT(stringf("# checksum: 0x%012llX calc: 0x%012llX %s", checksum, exp_checksum, (checksum == exp_checksum) ? "" : "~~~~~"));
			checksum = 0;
			exp_checksum = 0;
			frame = next_frame.at(frame);
		}
	};

	while (!rd.done()) {
		uint32_t hdr = rd.next_u32(true);
		if (hdr == 0xFFFFFFFF) {
			COMMENT("# desync");
			rd.skip_till_preamble();
			continue;
		}
		uint8_t type = (hdr >> 29) & 0x07;
		if (type == 0b001) {
			// Type 1 (short) packet
			uint8_t op = (hdr >> 27) & 0x03;
			switch(op) {
				case 0x00:
					COMMENT("# NOP ");
					// NOP
					break;
				case 0x01:
				    // READ
				    break;
				case 0x02: {
					// WRITE
					uint16_t reg = (hdr >> 13) & 0x3FFF;
					rd.curr_addr = reg;
					last_reg = reg;
					int count = hdr & 0x3FF;
					COMMENT("# write " << get_register_name(reg));
					if (reg == FAR) {
						if (count != 1)
							COMMENT("# bad FAR length " << count);
						exp_checksum = 0;
						checksum = 0;
						frame = rd.next_u32();
						word = 0;
						COMMENT(stringf("# frame 0x%08x", frame));
					} else if (reg == CRC) {
						uint32_t crc = 0;
						for(int i = 0; i < count; i++)
							crc = rd.next_u32(true);
						COMMENT(stringf("# CRC written=%08x calc=%08x %s", crc, rd.curr_crc, (crc == rd.curr_crc) ? "" : "*****"));
						rd.curr_crc = 0;
					} else if (reg == FDRI) {
						for(int i = 0; i < count; i++)
							process_word(rd.next_u32());
					} else if (reg == CMD) {
						uint32_t cmd = 0;
						for(int i = 0; i < count; i++)
							cmd = rd.next_u32();
						COMMENT(stringf("#     CMD %08x", cmd));
						if (cmd == 0x7)
							rd.curr_crc = 0;
					} else {
						for(int i = 0; i < count; i++)
							COMMENT(stringf("#     data %08x", rd.next_u32()));
					}

					if (reg == CRC && next_frame.count(frame)) {
						exp_checksum = 0;
						checksum = 0;
						frame = next_frame.at(frame);
					}

				} break;
			}
		} else if (type == 0b010) {
			// Type 2 (long) packet
			int count = hdr & 0x3FFFFFF;
			if (last_reg == FDRI) {
				for(int i = 0; i < count; i++)
					process_word(rd.next_u32());
			} else {
				for(int i = 0; i < count; i++)
					COMMENT(stringf("#     data %08x", rd.next_u32()));
			}
		} else {
			std::cout << stringf("# unknown packet type %01x (header: %08x)", type, hdr) << std::endl;
			return;
		}
	}
}

int main(int argc, char *argv[]) {
	if (argc < 2) {
		std::cerr << "Usage: dump_bitstream file.bit [frames.txt] [verbose]" << std::endl;
		return 2;
	}

	if (argc > 2) {
		std::ifstream frame_db(argv[2]);
		bool had_last = false;
		uint32_t last;
		uint32_t val;
		frame_db.unsetf(std::ios::dec);
		frame_db.unsetf(std::ios::hex);
		frame_db.unsetf(std::ios::oct);
		while (frame_db >> val) {
			if (had_last)
				next_frame[last] = val;
			last = val;
			had_last = true;
		}
	}

	if (argc > 3) {
		if (std::string(argv[3]) == "verbose")
			verbose_flag = true;
	}

	ByteStreamReader rd;
	std::ifstream file(argv[1], std::ios::binary);
	file.unsetf(std::ios::skipws);
	if (!file) {
		std::cerr << "Failed to open input file" << std::endl;
		return 2;
	}
	rd.data.insert(rd.data.begin(), std::istream_iterator<uint8_t>(file), std::istream_iterator<uint8_t>()); 
	parse_bitstream(rd);
}