/*
 * Copyright (c) 2023 Trackunit Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>

#include <string.h>
#include <stdarg.h>
#include <stdarg.h>

#include "gnss_nmea0183.h"
#include "gnss_parse.h"

#define GNSS_NMEA0183_PICO_DEGREES_IN_DEGREE      (1000000000000ULL)
#define GNSS_NMEA0183_PICO_DEGREES_IN_MINUTE      (GNSS_NMEA0183_PICO_DEGREES_IN_DEGREE / 60ULL)
#define GNSS_NMEA0183_PICO_DEGREES_IN_NANO_DEGREE (1000ULL)
#define GNSS_NMEA0183_NANO_KNOTS_IN_MMS           (1943861LL)

#define GNSS_NMEA0183_MESSAGE_SIZE_MIN      (6)
#define GNSS_NMEA0183_MESSAGE_CHECKSUM_SIZE (3)

#define GNSS_NMEA0183_GSV_HDR_ARG_CNT (4)
#define GNSS_NMEA0183_GSV_SV_ARG_CNT  (4)

#define GNSS_NMEA0183_GSV_PRN_GPS_RANGE      (32)
#define GNSS_NMEA0183_GSV_PRN_SBAS_OFFSET    (87)
#define GNSS_NMEA0183_GSV_PRN_GLONASS_OFFSET (64)
#define GNSS_NMEA0183_GSV_PRN_BEIDOU_OFFSET  (100)

struct gsv_header_args {
	const char *message_id;
	const char *number_of_messages;
	const char *message_number;
	const char *numver_of_svs;
};

struct gsv_sv_args {
	const char *prn;
	const char *elevation;
	const char *azimuth;
	const char *snr;
};

static int gnss_system_from_gsv_header_args(const struct gsv_header_args *args,
					    enum gnss_system *sv_system)
{
	switch (args->message_id[2]) {
	case 'A':
		*sv_system = GNSS_SYSTEM_GALILEO;
		break;
	case 'B':
		*sv_system = GNSS_SYSTEM_BEIDOU;
		break;
	case 'P':
		*sv_system = GNSS_SYSTEM_GPS;
		break;
	case 'L':
		*sv_system = GNSS_SYSTEM_GLONASS;
		break;
	case 'Q':
		*sv_system = GNSS_SYSTEM_QZSS;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static void align_satellite_with_gnss_system(enum gnss_system sv_system,
					     struct gnss_satellite *satellite)
{
	switch (sv_system) {
	case GNSS_SYSTEM_GPS:
		if (satellite->prn > GNSS_NMEA0183_GSV_PRN_GPS_RANGE) {
			satellite->system = GNSS_SYSTEM_SBAS;
			satellite->prn += GNSS_NMEA0183_GSV_PRN_SBAS_OFFSET;
			break;
		}

		satellite->system = GNSS_SYSTEM_GPS;
		break;

	case GNSS_SYSTEM_GLONASS:
		satellite->system = GNSS_SYSTEM_GLONASS;
		satellite->prn -= GNSS_NMEA0183_GSV_PRN_GLONASS_OFFSET;
		break;

	case GNSS_SYSTEM_GALILEO:
		satellite->system = GNSS_SYSTEM_GALILEO;
		break;

	case GNSS_SYSTEM_BEIDOU:
		satellite->system = GNSS_SYSTEM_BEIDOU;
		satellite->prn -= GNSS_NMEA0183_GSV_PRN_BEIDOU_OFFSET;
		break;

	case GNSS_SYSTEM_QZSS:
		satellite->system = GNSS_SYSTEM_QZSS;
		break;

	case GNSS_SYSTEM_IRNSS:
	case GNSS_SYSTEM_IMES:
	case GNSS_SYSTEM_SBAS:
		break;
	}
}

uint8_t gnss_nmea0183_checksum(const char *str)
{
	uint8_t checksum = 0;
	size_t end;

	__ASSERT(str != NULL, "str argument must be provided");

	end = strlen(str);
	for (size_t i = 0; i < end; i++) {
		checksum = checksum ^ str[i];
	}

	return checksum;
}

int gnss_nmea0183_snprintk(char *str, size_t size, const char *fmt, ...)
{
	va_list ap;
	uint8_t checksum;
	int pos;
	int len;

	__ASSERT(str != NULL, "str argument must be provided");
	__ASSERT(fmt != NULL, "fmt argument must be provided");

	if (size < GNSS_NMEA0183_MESSAGE_SIZE_MIN) {
		return -ENOMEM;
	}

	str[0] = '$';

	va_start(ap, fmt);
	pos = vsnprintk(&str[1], size - 1, fmt, ap) + 1;
	va_end(ap);

	if (pos < 0) {
		return -EINVAL;
	}

	len = pos + GNSS_NMEA0183_MESSAGE_CHECKSUM_SIZE;

	if ((size - 1) < len) {
		return -ENOMEM;
	}

	checksum = gnss_nmea0183_checksum(&str[1]);
	pos = snprintk(&str[pos], size - pos, "*%02X", checksum);
	if (pos != 3) {
		return -EINVAL;
	}

	str[len] = '\0';
	return len;
}

int gnss_nmea0183_ddmm_mmmm_to_ndeg(const char *ddmm_mmmm, int64_t *ndeg)
{
	uint64_t pico_degrees = 0;
	int8_t decimal = -1;
	int8_t pos = 0;
	uint64_t increment;

	__ASSERT(ddmm_mmmm != NULL, "ddmm_mmmm argument must be provided");
	__ASSERT(ndeg != NULL, "ndeg argument must be provided");

	/* Find decimal */
	while (ddmm_mmmm[pos] != '\0') {
		/* Verify if char is decimal */
		if (ddmm_mmmm[pos] == '.') {
			decimal = pos;
			break;
		}

		/* Advance position */
		pos++;
	}

	/* Verify decimal was found and placed correctly */
	if (decimal < 1) {
		return -EINVAL;
	}

	/* Validate potential degree fraction is within bounds */
	if (decimal > 1 && ddmm_mmmm[decimal - 2] > '5') {
		return -EINVAL;
	}

	/* Convert minute fraction to pico degrees and add it to pico_degrees */
	pos = decimal + 1;
	increment = (GNSS_NMEA0183_PICO_DEGREES_IN_MINUTE / 10);
	while (ddmm_mmmm[pos] != '\0') {
		/* Verify char is decimal */
		if (ddmm_mmmm[pos] < '0' || ddmm_mmmm[pos] > '9') {
			return -EINVAL;
		}

		/* Add increment to pico_degrees */
		pico_degrees += (ddmm_mmmm[pos] - '0') * increment;

		/* Update unit */
		increment /= 10;

		/* Increment position */
		pos++;
	}

	/* Convert minutes and degrees to pico_degrees */
	pos = decimal - 1;
	increment = GNSS_NMEA0183_PICO_DEGREES_IN_MINUTE;
	while (pos >= 0) {
		/* Check if digit switched from minutes to degrees */
		if ((decimal - pos) == 3) {
			/* Reset increment to degrees */
			increment = GNSS_NMEA0183_PICO_DEGREES_IN_DEGREE;
		}

		/* Verify char is decimal */
		if (ddmm_mmmm[pos] < '0' || ddmm_mmmm[pos] > '9') {
			return -EINVAL;
		}

		/* Add increment to pico_degrees */
		pico_degrees += (ddmm_mmmm[pos] - '0') * increment;

		/* Update unit */
		increment *= 10;

		/* Decrement position */
		pos--;
	}

	/* Convert to nano degrees */
	*ndeg = (int64_t)(pico_degrees / GNSS_NMEA0183_PICO_DEGREES_IN_NANO_DEGREE);
	return 0;
}

bool gnss_nmea0183_validate_message(char **argv, uint16_t argc)
{
	int32_t tmp = 0;
	uint8_t checksum = 0;
	size_t len;

	__ASSERT(argv != NULL, "argv argument must be provided");

	/* Message must contain message id and checksum */
	if (argc < 2) {
		return false;
	}

	/* First argument should start with '$' which is not covered by checksum */
	if ((argc < 1) || (argv[0][0] != '$')) {
		return false;
	}

	len = strlen(argv[0]);
	for (uint16_t u = 1; u < len; u++) {
		checksum ^= argv[0][u];
	}
	checksum ^= ',';

	/* Cover all except last argument which contains the checksum*/
	for (uint16_t i = 1; i < (argc - 1); i++) {
		len = strlen(argv[i]);
		for (uint16_t u = 0; u < len; u++) {
			checksum ^= argv[i][u];
		}
		checksum ^= ',';
	}

	if ((gnss_parse_atoi(argv[argc - 1], 16, &tmp) < 0) ||
	    (tmp > UINT8_MAX) ||
	    (tmp < 0)) {
		return false;
	}

	return checksum == (uint8_t)tmp;
}

int gnss_nmea0183_knots_to_mms(const char *str, int64_t *mms)
{
	int ret;

	__ASSERT(str != NULL, "str argument must be provided");
	__ASSERT(mms != NULL, "mms argument must be provided");

	ret = gnss_parse_dec_to_nano(str, mms);
	if (ret < 0) {
		return ret;
	}

	*mms = (*mms) / GNSS_NMEA0183_NANO_KNOTS_IN_MMS;
	return 0;
}

int gnss_nmea0183_parse_hhmmss(const char *hhmmss, struct gnss_time *utc)
{
	int64_t i64;
	int32_t i32;
	char part[3] = {0};

	__ASSERT(hhmmss != NULL, "hhmmss argument must be provided");
	__ASSERT(utc != NULL, "utc argument must be provided");

	if (strlen(hhmmss) < 6) {
		return -EINVAL;
	}

	memcpy(part, hhmmss, 2);
	if ((gnss_parse_atoi(part, 10, &i32) < 0) ||
	    (i32 < 0) ||
	    (i32 > 23)) {
		return -EINVAL;
	}

	utc->hour = (uint8_t)i32;

	memcpy(part, &hhmmss[2], 2);
	if ((gnss_parse_atoi(part, 10, &i32) < 0) ||
	    (i32 < 0) ||
	    (i32 > 59)) {
		return -EINVAL;
	}

	utc->minute = (uint8_t)i32;

	if ((gnss_parse_dec_to_milli(&hhmmss[4], &i64) < 0) ||
	    (i64 < 0) ||
	    (i64 > 59999)) {
		return -EINVAL;
	}

	utc->millisecond = (uint16_t)i64;
	return 0;
}

int gnss_nmea0183_parse_ddmmyy(const char *ddmmyy, struct gnss_time *utc)
{
	int32_t i32;
	char part[3] = {0};

	__ASSERT(ddmmyy != NULL, "ddmmyy argument must be provided");
	__ASSERT(utc != NULL, "utc argument must be provided");

	if (strlen(ddmmyy) != 6) {
		return -EINVAL;
	}

	memcpy(part, ddmmyy, 2);
	if ((gnss_parse_atoi(part, 10, &i32) < 0) ||
	    (i32 < 1) ||
	    (i32 > 31)) {
		return -EINVAL;
	}

	utc->month_day = (uint8_t)i32;

	memcpy(part, &ddmmyy[2], 2);
	if ((gnss_parse_atoi(part, 10, &i32) < 0) ||
	    (i32 < 1) ||
	    (i32 > 12)) {
		return -EINVAL;
	}

	utc->month = (uint8_t)i32;

	memcpy(part, &ddmmyy[4], 2);
	if ((gnss_parse_atoi(part, 10, &i32) < 0) ||
	    (i32 < 0) ||
	    (i32 > 99)) {
		return -EINVAL;
	}

	utc->century_year = (uint8_t)i32;
	return 0;
}

int gnss_nmea0183_parse_rmc(const char **argv, uint16_t argc, struct gnss_data *data)
{
	int64_t tmp;

	__ASSERT(argv != NULL, "argv argument must be provided");
	__ASSERT(data != NULL, "data argument must be provided");

	if (argc < 10)  {
		return -EINVAL;
	}

	/* Validate GNSS has fix */
	if (argv[2][0] == 'V') {
		return 0;
	}

	if (argv[2][0] != 'A') {
		return -EINVAL;
	}

	/* Parse UTC time */
	if ((gnss_nmea0183_parse_hhmmss(argv[1], &data->utc) < 0)) {
		return -EINVAL;
	}

	/* Validate cardinal directions */
	if (((argv[4][0] != 'N') && (argv[4][0] != 'S')) ||
	    ((argv[6][0] != 'E') && (argv[6][0] != 'W'))) {
		return -EINVAL;
	}

	/* Parse coordinates */
	if ((gnss_nmea0183_ddmm_mmmm_to_ndeg(argv[3], &data->nav_data.latitude) < 0) ||
	    (gnss_nmea0183_ddmm_mmmm_to_ndeg(argv[5], &data->nav_data.longitude) < 0)) {
		return -EINVAL;
	}

	/* Align sign of coordinates with cardinal directions */
	data->nav_data.latitude = argv[4][0] == 'N'
				    ? data->nav_data.latitude
				    : -data->nav_data.latitude;

	data->nav_data.longitude = argv[6][0] == 'E'
				     ? data->nav_data.longitude
				     : -data->nav_data.longitude;

	/* Parse speed */
	if ((gnss_nmea0183_knots_to_mms(argv[7], &tmp) < 0) ||
	    (tmp > UINT32_MAX)) {
		return -EINVAL;
	}

	data->nav_data.speed = (uint32_t)tmp;

	/* Parse bearing */
	if ((gnss_parse_dec_to_milli(argv[8], &tmp) < 0) ||
	    (tmp > 359999) ||
	    (tmp < 0)) {
		return -EINVAL;
	}

	data->nav_data.bearing = (uint32_t)tmp;

	/* Parse UTC date */
	if ((gnss_nmea0183_parse_ddmmyy(argv[9], &data->utc) < 0)) {
		return -EINVAL;
	}

	return 0;
}

static int parse_gga_fix_quality(const char *str, enum gnss_fix_quality *fix_quality)
{
	__ASSERT(str != NULL, "str argument must be provided");
	__ASSERT(fix_quality != NULL, "fix_quality argument must be provided");

	if ((str[1] != ((char)'\0')) || (str[0] < ((char)'0')) || (((char)'6') < str[0])) {
		return -EINVAL;
	}

	(*fix_quality) = (enum gnss_fix_quality)(str[0] - ((char)'0'));
	return 0;
}

static enum gnss_fix_status fix_status_from_fix_quality(enum gnss_fix_quality fix_quality)
{
	enum gnss_fix_status fix_status = GNSS_FIX_STATUS_NO_FIX;

	switch (fix_quality) {
	case GNSS_FIX_QUALITY_GNSS_SPS:
	case GNSS_FIX_QUALITY_GNSS_PPS:
		fix_status = GNSS_FIX_STATUS_GNSS_FIX;
		break;

	case GNSS_FIX_QUALITY_DGNSS:
	case GNSS_FIX_QUALITY_RTK:
	case GNSS_FIX_QUALITY_FLOAT_RTK:
		fix_status = GNSS_FIX_STATUS_DGNSS_FIX;
		break;

	case GNSS_FIX_QUALITY_ESTIMATED:
		fix_status = GNSS_FIX_STATUS_ESTIMATED_FIX;
		break;

	default:
		break;
	}

	return fix_status;
}

int gnss_nmea0183_parse_gga(const char **argv, uint16_t argc, struct gnss_data *data)
{
	int32_t tmp32;
	int64_t tmp64;

	__ASSERT(argv != NULL, "argv argument must be provided");
	__ASSERT(data != NULL, "data argument must be provided");

	if (argc < 12)  {
		return -EINVAL;
	}

	/* Parse fix quality and status */
	if (parse_gga_fix_quality(argv[6], &data->info.fix_quality) < 0) {
		return -EINVAL;
	}

	data->info.fix_status = fix_status_from_fix_quality(data->info.fix_quality);

	/* Validate GNSS has fix */
	if (data->info.fix_status == GNSS_FIX_STATUS_NO_FIX) {
		return 0;
	}

	/* Parse number of satellites */
	if ((gnss_parse_atoi(argv[7], 10, &tmp32) < 0) ||
	    (tmp32 > UINT16_MAX) ||
	    (tmp32 < 0)) {
		return -EINVAL;
	}

	data->info.satellites_cnt = (uint16_t)tmp32;

	/* Parse HDOP */
	if ((gnss_parse_dec_to_milli(argv[8], &tmp64) < 0) ||
	    (tmp64 > UINT16_MAX) ||
	    (tmp64 < 0)) {
		return -EINVAL;
	}

	data->info.hdop = (uint16_t)tmp64;

	/* Parse altitude */
	if ((gnss_parse_dec_to_milli(argv[11], &tmp64) < 0) ||
	    (tmp64 > INT32_MAX) ||
	    (tmp64 < INT32_MIN)) {
		return -EINVAL;
	}

	data->nav_data.altitude = (int32_t)tmp64;
	return 0;
}

static int parse_gsv_svs(struct gnss_satellite *satellites, const struct gsv_sv_args *svs,
			 uint16_t svs_size)
{
	int32_t i32;

	for (uint16_t i = 0; i < svs_size; i++) {
		/* Parse PRN */
		if ((gnss_parse_atoi(svs[i].prn, 10, &i32) < 0) ||
		    (i32 < 0) || (i32 > UINT16_MAX)) {
			return -EINVAL;
		}

		satellites[i].prn = (uint16_t)i32;

		/* Parse elevation */
		if ((gnss_parse_atoi(svs[i].elevation, 10, &i32) < 0) ||
		    (i32 < 0) || (i32 > 90)) {
			return -EINVAL;
		}

		satellites[i].elevation = (uint8_t)i32;

		/* Parse azimuth */
		if ((gnss_parse_atoi(svs[i].azimuth, 10, &i32) < 0) ||
		    (i32 < 0) || (i32 > 359)) {
			return -EINVAL;
		}

		satellites[i].azimuth = (uint16_t)i32;

		/* Parse SNR */
		if (strlen(svs[i].snr) == 0) {
			satellites[i].snr = 0;
			satellites[i].is_tracked = false;
			continue;
		}

		if ((gnss_parse_atoi(svs[i].snr, 10, &i32) < 0) ||
			(i32 < 0) || (i32 > 99)) {
			return -EINVAL;
		}

		satellites[i].snr = (uint16_t)i32;
		satellites[i].is_tracked = true;
	}

	return 0;
}

int gnss_nmea0183_parse_gsv_header(const char **argv, uint16_t argc,
				   struct gnss_nmea0183_gsv_header *header)
{
	const struct gsv_header_args *args = (const struct gsv_header_args *)argv;
	int i32;

	__ASSERT(argv != NULL, "argv argument must be provided");
	__ASSERT(header != NULL, "header argument must be provided");

	if (argc < 4) {
		return -EINVAL;
	}

	/* Parse GNSS sv_system */
	if (gnss_system_from_gsv_header_args(args, &header->system) < 0) {
		return -EINVAL;
	}

	/* Parse number of messages */
	if ((gnss_parse_atoi(args->number_of_messages, 10, &i32) < 0) ||
		(i32 < 0) || (i32 > UINT16_MAX)) {
		return -EINVAL;
	}

	header->number_of_messages = (uint16_t)i32;

	/* Parse message number */
	if ((gnss_parse_atoi(args->message_number, 10, &i32) < 0) ||
		(i32 < 0) || (i32 > UINT16_MAX)) {
		return -EINVAL;
	}

	header->message_number = (uint16_t)i32;

	/* Parse message number */
	if ((gnss_parse_atoi(args->numver_of_svs, 10, &i32) < 0) ||
		(i32 < 0) || (i32 > UINT16_MAX)) {
		return -EINVAL;
	}

	header->number_of_svs = (uint16_t)i32;
	return 0;
}

int gnss_nmea0183_parse_gsv_svs(const char **argv, uint16_t argc,
				struct gnss_satellite *satellites, uint16_t size)
{
	const struct gsv_header_args *header_args = (const struct gsv_header_args *)argv;
	const struct gsv_sv_args *sv_args = (const struct gsv_sv_args *)(argv + 4);
	uint16_t sv_args_size;
	enum gnss_system sv_system;

	__ASSERT(argv != NULL, "argv argument must be provided");
	__ASSERT(satellites != NULL, "satellites argument must be provided");

	if (argc < 9) {
		return 0;
	}

	sv_args_size = (argc - GNSS_NMEA0183_GSV_HDR_ARG_CNT) / GNSS_NMEA0183_GSV_SV_ARG_CNT;

	if (size < sv_args_size) {
		return -ENOMEM;
	}

	if (parse_gsv_svs(satellites, sv_args, sv_args_size) < 0) {
		return -EINVAL;
	}

	if (gnss_system_from_gsv_header_args(header_args, &sv_system) < 0) {
		return -EINVAL;
	}

	for (uint16_t i = 0; i < sv_args_size; i++) {
		align_satellite_with_gnss_system(sv_system, &satellites[i]);
	}

	return (int)sv_args_size;
}
