#!/usr/bin/python3
# -*- coding: utf-8 -*-


import numpy as np
import pprint
import sys, os, time, datetime

sys.path.insert(0,'..')
from functions import *

import csv
import argparse

pp = pprint.PrettyPrinter(indent=4)

parser = argparse.ArgumentParser()
parser.add_argument("input_file")
parser.add_argument("output_file")
args = parser.parse_args()

#os.system('cls')

size = os.stat(args.input_file).st_size
print("file name: {} size: {} bytes".format(args.input_file, size))
f = open(args.input_file, "rb")
logFile = open(args.output_file, "w", newline='')

dataset = """
/*-------RAW-----------*/
	uint32_t pressure_cis_raw;    // pack 1 x 4
	uint32_t temperature_cis_raw; //    + 1 x 4
	
	uint32_t pressure_spi_raw;
	uint32_t temperature_i2c_raw;
	
	uint32_t temperature_spi_raw;
	uint32_t adc_temperature_raw;
	
	int32_t  temperature_mpu_raw;
	uint32_t adc_temperature_internal_raw;
	
	uint32_t	adc_voltage_raw;
	uint32_t	adc_current_raw;
	
	struct vector_Uint accel_raw; // pack 3 x 4
	struct vector_Uint gyro_raw;  //    + 3 x 4
	
	struct vector_Uint mag_raw; // pack 3 x 4
	                            //    + 1 x 4
  int32_t temperature_mag_raw;
	
	/*-----Computed--------*/
	
	double pressure_cis; // no packing needed 1 x 8
	
	double temperature_cis;	
	
	double pressure_spi;	
	
	double temperature_i2c;	
	
	double temperature_spi;	
	
	double adc_temperature;	
	
	double adc_temperature_internal;			
	
	double adc_voltage;	

	double adc_current;		

	double temperature_mpu;	
	
	struct vector accel; // no packing needed 3 x 8
	struct vector gyro;
	struct vector rot;
	
	struct vector mag;
	double temperature_mag;
	
	struct vector global_accel;
	struct vector pos;

	/*-----------gps------------*/
	int32_t longitude;
	int32_t latitude;
	
	int32_t altitude;
	uint32_t time;
	
	uint32_t hdop;
	int32_t mag_head; //heading
	
	uint32_t count;
	uint32_t crc;
"""
master = PktParser(dataset)
slave  = PktParser(dataset, master.end)
fusion = PktParser(dataset, slave.end)

length = fusion.end + 2

print("expected length of row: {}".format(fusion.end))
total = size/fusion.end
print("expected row count: {}".format(total))
print()
print(master.keys())
time.sleep(1)

count = 0
buf = b''
obj = None

cs = None
		

def check():
	#pp.pprint(x)
	
	if buf[fusion.end:fusion.end+2] != b"\r\n":
		print("[{:8}/{:8}] error missing EOL!".format(count, total))
		return
	
	m = master.parse(buf)
	s = slave.parse(buf)
	f = fusion.parse(buf)
	
	crc_m = sum(buf[:master.end-4])
	crc_s = sum(buf[master.end:slave.end-4])
	crc_f = sum(buf[slave.end:fusion.end-4])
	
	
	if crc_m != m["crc"]:
		print("[{:8}/{:8}] crc error in master! diff = {:12}".format(count, total, crc_m - m["crc"]))
		return
	#if crc_s != s["crc"]:
		#print("[{:8}/{:8}] crc error in slave!".format(count, total))
	#	return
	#if crc_f != f["crc"]:
		#print("[{:8}/{:8}] crc error in fusion!".format(count, total))
	#	return
	
	data = m
	# for prop in slave.keys():
		# if s:
			# data["slave_" + prop] = s[prop]
		# if f:
			# data["fusion_" + prop] = f[prop]
	
	data["slave_count"] = s["count"]
	data["slave_time"] = s["time"]
	
	return data

try:
	byte = b'A'
	while byte != b"":
		# Do stuff with byte.
		if len(buf) >= length:
			obj = check()
			
			if obj:

				if cs == None:
					cs = csv.DictWriter(logFile, obj.keys())
					cs.writeheader()
				
				cs.writerow(obj)
			
				if count % 10000 == 1:
					print("[{:8}/{:8}] ...{:.2%}".format(count, total, count/total))
			
				count += 1
			pos = buf.find(b"\r\n")
			if pos == -1:
				print("[{:8}/{:8}] can't find next line!".format(count, total))
			
			#if not obj and pos >= 0:
				#print("[{:8}] skipping {:4} chars".format(count, pos+2))
			
			if pos != fusion.end and not obj:
				print("[{:8}/{:8}] expected {:4} bytes but got {:4}".format(count, total, fusion.end+2, pos+2))
			
			buf = buf[pos+2:]
		else:
			byte = f.read(length)
			buf += byte
finally:
	f.close()
	#fw.close()