#include "FitCANBus.h"
#include <future>
#include <chrono>
#include <assert.h>
#include <iostream>

using namespace std;

FitCANBus* FitCANBusTest;

void writeMessage(DWORD canid, FITAPI::CFitekCanBusControl::CanFrameFormat type, int rtr) {
	int count = 0;

	FITAPI::CFitekCanBusControl::CanFrameInfor msg;
	msg.type = type;
	msg.rtr = rtr;
	msg.data_len = 8;
	for (int i = 0; i < 8; i++) {
		msg.data[i] = i + ((count & 0xf) << 4);
	}
	msg.id = canid;
	FitCANBusTest->writeMessage(&msg);
}

typedef enum {
	IDX_CMD = 0,
	IDX_CAN_NAME,
	IDX_CAN_RATE,
	IDX_CAN_ID,
	IDX_CAN_BITS,
	IDX_CAN_RTR,
	IDX_TX_FILTERS,
} ARGV_DEF;

void main(int argc, char *argv[])
{
	char* canbus;
	int baudrate;
	DWORD canid = 0x18ea0000;
	int t = 29;
	int rtr = 0;
	int filter;
	DWORD pattern[CANBUS_MAX_FILTER_SIZE];
	DWORD mask[CANBUS_MAX_FILTER_SIZE];
	memset(pattern, 0, sizeof(pattern));
	memset(mask, 0, sizeof(mask));
	if (argc <= IDX_CAN_RATE) {
		printf_s("\n==== Arguments and default value ====\n");
		printf_s("<CAN_Name> <CAN_baudRate> <CANID> <CANID_Bits> <CANRTR> <FilterPatten0> <FilterMask0> ... <FilterPatten15> <FilterMask15>\n");
		printf_s("\t<CAN_Name> is must to setup.\n");
		printf_s("\t<CAN_baudRate> is must to setup.\n");
		printf_s("\t<CANID> (hex) = %x\n", canid);
		printf_s("\t<CANID_Bits> = %d\n", t);
		printf_s("\t<CANRTR> = %d\n", rtr);
		printf_s("\t<FilterPatten%%d> and <FilterMask%%d> are dependent each other\n");
		printf_s("EX:> FitCANBus.exe COM3 250 12345678 29 1 0 0\n");
		exit(-1);
	}
	canbus = argv[IDX_CAN_NAME];
	baudrate = strtol(argv[IDX_CAN_RATE], NULL, 10) * 1000;
	if (argc > IDX_CAN_ID)
		canid = strtol(argv[IDX_CAN_ID], NULL, 16);
	if (argc > IDX_CAN_BITS)
		t = strtol(argv[IDX_CAN_BITS], NULL, 10);
	if (argc > IDX_CAN_RTR)
		rtr = strtol(argv[IDX_CAN_RTR], NULL, 10);
	printf_s("para_num=%d, bus=%s, baudrate=%d, CANID=%d(0x%X), type=%d , rtr=%d\n",
		argc, canbus, baudrate, canid, canid, t, rtr);

	for (filter = 0; filter < 15; filter++) {
		if (argc <= filter * 2 + IDX_TX_FILTERS + 1)
			break;
		pattern[filter] = strtol(argv[filter * 2 + IDX_TX_FILTERS], NULL, 16);
		mask[filter] = strtol(argv[filter * 2 + IDX_TX_FILTERS + 1], NULL, 16);
		printf_s("filter[%d] : pattern=%d(0x%X), mask=%d(0x%X)\n",
			filter, pattern[filter], pattern[filter], mask[filter], mask[filter]);
	}
	FITAPI::CFitekCanBusControl::CanFrameFormat type;
	switch (t) {
	case 11:
		type = FITAPI::CFitekCanBusControl::CanFrameFormat::CP_11Bit;
		break;
	case 29:
		type = FITAPI::CFitekCanBusControl::CanFrameFormat::CP_29Bit;
		break;
	default:
		printf_s("Parameters type error\n");
		exit(-1);
	}

	FitCANBusTest = new FitCANBus(canbus);
	if (FitCANBusTest->init(baudrate) < 0)
		goto exit;
	if (FitCANBusTest->startReading(filter, pattern, mask))
		goto exit;
	if (FitCANBusTest->FintekCanbus_SetId(canid, type))
		goto exit;
	async(writeMessage, canid, type, rtr);
	char tmp[MAX_PATH];
	scanf_s("%s", &tmp);
	
exit:
	
	delete FitCANBusTest;
}
