/* SPDX-License-Identifier: GPL-2.0-or-later */

#include "data.h"

#include <ctype.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "utils.h"

void print_data(const uint8_t data[], size_t data_size, enum data_type type)
{
	if (data_size == 0)
		return;

	switch (type) {
	case DATA_TYPE_BOOL:
		bool value = false;
		for (size_t i = 0; i < data_size; ++i) {
			if (data[i] != 0) {
				value = true;
				break;
			}
		}
		printf("%s\n", value ? "true" : "false");
		break;
	case DATA_TYPE_UINT8:
		if (data_size != 1) {
			fprintf(stderr,
				"warning: expected size of 1, got %zu\n",
				data_size);
		}

		if (data_size >= 1)
			printf("%u\n", *(uint8_t *)data);
		break;
	case DATA_TYPE_UINT16:
		if (data_size != 2) {
			fprintf(stderr,
				"warning: expected size of 2, got %zu\n",
				data_size);
		}

		if (data_size >= 2)
			printf("%u\n", *(uint16_t *)data);
		break;
	case DATA_TYPE_UINT32:
		if (data_size != 4) {
			fprintf(stderr,
				"warning: expected size of 4, got %zu\n",
				data_size);
		}

		if (data_size >= 4)
			printf("%u\n", *(uint32_t *)data);
		break;
	case DATA_TYPE_ASCII:
		for (size_t i = 0; i < data_size; ++i) {
			char c = data[i];
			if (isprint(c))
				printf("%c", c);
		}
		printf("\n");
		break;
	case DATA_TYPE_UNICODE:
		char *chars = to_chars((const CHAR16 *)data, data_size);
		printf("%s\n", chars);
		free(chars);
		break;
	case DATA_TYPE_RAW:
		fwrite(data, 1, data_size, stdout);
		break;
	}
}

static uint64_t parse_uint(const char source[],
			   const char type[],
			   unsigned long long max)
{
	char *end;
	unsigned long long uint = strtoull(source, &end, /*base=*/0);
	if (*end != '\0') {
		fprintf(stderr, "Trailing characters in \"%s\": %s\n",
			source, end);
		return UINT64_MAX;
	}
	if (uint > max) {
		fprintf(stderr, "Invalid %s value: %llu\n", type, uint);
		return UINT64_MAX;
	}

	return uint;
}

void *make_data(const char source[], size_t *data_size, enum data_type type)
{
	switch (type) {
	void *data;
	bool boolean;
	unsigned long long uint;

	case DATA_TYPE_BOOL:
		if (str_eq(source, "true")) {
			boolean = true;
		} else if (str_eq(source, "false")) {
			boolean = false;
		} else {
			fprintf(stderr, "Invalid boolean value: \"%s\"\n",
				source);
			return NULL;
		}

		*data_size = 1;
		data = xmalloc(*data_size);
		*(uint8_t *)data = boolean;
		return data;
	case DATA_TYPE_UINT8:
		uint = parse_uint(source, "uint8", UINT8_MAX);
		if (uint == UINT64_MAX)
			return NULL;

		*data_size = 1;
		data = xmalloc(*data_size);
		*(uint8_t *)data = uint;
		return data;
	case DATA_TYPE_UINT16:
		uint = parse_uint(source, "uint16", UINT16_MAX);
		if (uint == UINT64_MAX)
			return NULL;

		*data_size = 2;
		data = xmalloc(*data_size);
		*(uint16_t *)data = uint;
		return data;
	case DATA_TYPE_UINT32:
		uint = parse_uint(source, "uint32", UINT32_MAX);
		if (uint == UINT64_MAX)
			return NULL;

		*data_size = 4;
		data = xmalloc(*data_size);
		*(uint32_t *)data = uint;
		return data;
	case DATA_TYPE_ASCII:
		*data_size = strlen(source) + 1;
		return strdup(source);
	case DATA_TYPE_UNICODE:
		return to_uchars(source, data_size);
	case DATA_TYPE_RAW:
		fprintf(stderr, "Raw data type is output only\n");
		return NULL;
	}

	return NULL;
}

bool parse_data_type(const char str[], enum data_type *type)
{
	if (str_eq(str, "bool"))
		*type = DATA_TYPE_BOOL;
	else if (str_eq(str, "uint8"))
		*type = DATA_TYPE_UINT8;
	else if (str_eq(str, "uint16"))
		*type = DATA_TYPE_UINT16;
	else if (str_eq(str, "uint32"))
		*type = DATA_TYPE_UINT32;
	else if (str_eq(str, "ascii"))
		*type = DATA_TYPE_ASCII;
	else if (str_eq(str, "unicode"))
		*type = DATA_TYPE_UNICODE;
	else if (str_eq(str, "raw"))
		*type = DATA_TYPE_RAW;
	else
		return false;

	return true;
}
