/**
 * Describes utility functions for parsing CPER into JSON IR.
 *
 * Author: Lawrence.Tang@arm.com
 **/

#include <stdio.h>
#include <json.h>
#include <string.h>
#include <libcper/Cper.h>
#include <libcper/cper-utils.h>

//The available severity types for CPER.
const char *CPER_SEVERITY_TYPES[4] = { "Recoverable", "Fatal", "Corrected",
				       "Informational" };

//Converts the given generic CPER error status to JSON IR.
json_object *
cper_generic_error_status_to_ir(EFI_GENERIC_ERROR_STATUS *error_status)
{
	json_object *error_status_ir = json_object_new_object();

	//Error type.
	json_object_object_add(error_status_ir, "errorType",
			       integer_to_readable_pair_with_desc(
				       error_status->Type, 18,
				       CPER_GENERIC_ERROR_TYPES_KEYS,
				       CPER_GENERIC_ERROR_TYPES_VALUES,
				       CPER_GENERIC_ERROR_TYPES_DESCRIPTIONS,
				       "Unknown (Reserved)"));

	//Boolean bit fields.
	json_object_object_add(
		error_status_ir, "addressSignal",
		json_object_new_boolean(error_status->AddressSignal));
	json_object_object_add(
		error_status_ir, "controlSignal",
		json_object_new_boolean(error_status->ControlSignal));
	json_object_object_add(
		error_status_ir, "dataSignal",
		json_object_new_boolean(error_status->DataSignal));
	json_object_object_add(
		error_status_ir, "detectedByResponder",
		json_object_new_boolean(error_status->DetectedByResponder));
	json_object_object_add(
		error_status_ir, "detectedByRequester",
		json_object_new_boolean(error_status->DetectedByRequester));
	json_object_object_add(
		error_status_ir, "firstError",
		json_object_new_boolean(error_status->FirstError));
	json_object_object_add(
		error_status_ir, "overflowDroppedLogs",
		json_object_new_boolean(error_status->OverflowNotLogged));

	return error_status_ir;
}

//Converts the given CPER-JSON generic error status into a CPER structure.
void ir_generic_error_status_to_cper(
	json_object *error_status, EFI_GENERIC_ERROR_STATUS *error_status_cper)
{
	error_status_cper->Type = readable_pair_to_integer(
		json_object_object_get(error_status, "errorType"));
	error_status_cper->AddressSignal = json_object_get_boolean(
		json_object_object_get(error_status, "addressSignal"));
	error_status_cper->ControlSignal = json_object_get_boolean(
		json_object_object_get(error_status, "controlSignal"));
	error_status_cper->DataSignal = json_object_get_boolean(
		json_object_object_get(error_status, "dataSignal"));
	error_status_cper->DetectedByResponder = json_object_get_boolean(
		json_object_object_get(error_status, "detectedByResponder"));
	error_status_cper->DetectedByRequester = json_object_get_boolean(
		json_object_object_get(error_status, "detectedByRequester"));
	error_status_cper->FirstError = json_object_get_boolean(
		json_object_object_get(error_status, "firstError"));
	error_status_cper->OverflowNotLogged = json_object_get_boolean(
		json_object_object_get(error_status, "overflowDroppedLogs"));
}

//Converts a single uniform struct of UINT64s into intermediate JSON IR format, given names for each field in byte order.
json_object *uniform_struct64_to_ir(UINT64 *start, int len, const char *names[])
{
	json_object *result = json_object_new_object();

	UINT64 *cur = start;
	for (int i = 0; i < len; i++) {
		json_object_object_add(result, names[i],
				       json_object_new_uint64(*cur));
		cur++;
	}

	return result;
}

//Converts a single uniform struct of UINT32s into intermediate JSON IR format, given names for each field in byte order.
json_object *uniform_struct_to_ir(UINT32 *start, int len, const char *names[])
{
	json_object *result = json_object_new_object();

	UINT32 *cur = start;
	for (int i = 0; i < len; i++) {
		UINT32 value;
		memcpy(&value, cur, sizeof(UINT32));
		json_object_object_add(result, names[i],
				       json_object_new_uint64(value));
		cur++;
	}

	return result;
}

//Converts a single object containing UINT32s into a uniform struct.
void ir_to_uniform_struct64(json_object *ir, UINT64 *start, int len,
			    const char *names[])
{
	UINT64 *cur = start;
	for (int i = 0; i < len; i++) {
		*cur = json_object_get_uint64(
			json_object_object_get(ir, names[i]));
		cur++;
	}
}

//Converts a single object containing UINT32s into a uniform struct.
void ir_to_uniform_struct(json_object *ir, UINT32 *start, int len,
			  const char *names[])
{
	UINT32 *cur = start;
	for (int i = 0; i < len; i++) {
		*cur = (UINT32)json_object_get_uint64(
			json_object_object_get(ir, names[i]));
		cur++;
	}
}

//Converts a single integer value to an object containing a value, and a readable name if possible.
json_object *integer_to_readable_pair(UINT64 value, int len, const int keys[],
				      const char *values[],
				      const char *default_value)
{
	json_object *result = json_object_new_object();
	json_object_object_add(result, "value", json_object_new_uint64(value));

	//Search for human readable name, add.
	const char *name = default_value;
	for (int i = 0; i < len; i++) {
		if ((UINT64)keys[i] == value) {
			name = values[i];
		}
	}

	json_object_object_add(result, "name", json_object_new_string(name));
	return result;
}

//Converts a single integer value to an object containing a value, readable name and description if possible.
json_object *integer_to_readable_pair_with_desc(int value, int len,
						const int keys[],
						const char *values[],
						const char *descriptions[],
						const char *default_value)
{
	json_object *result = json_object_new_object();
	json_object_object_add(result, "value", json_object_new_int(value));

	//Search for human readable name, add.
	const char *name = default_value;
	for (int i = 0; i < len; i++) {
		if (keys[i] == value) {
			name = values[i];
			json_object_object_add(
				result, "description",
				json_object_new_string(descriptions[i]));
		}
	}

	json_object_object_add(result, "name", json_object_new_string(name));
	return result;
}

//Returns a single UINT64 value from the given readable pair object.
//Assumes the integer value is held in the "value" field.
UINT64 readable_pair_to_integer(json_object *pair)
{
	return json_object_get_uint64(json_object_object_get(pair, "value"));
}

//Converts the given 64 bit bitfield to IR, assuming bit 0 starts on the left.
json_object *bitfield_to_ir(UINT64 bitfield, int num_fields,
			    const char *names[])
{
	json_object *result = json_object_new_object();
	for (int i = 0; i < num_fields; i++) {
		json_object_object_add(result, names[i],
				       json_object_new_boolean((bitfield >> i) &
							       0x1));
	}

	return result;
}

//Filters properties based on Validation Bits.
// Refer to CPER spec for vbit_idx to be passed here.
void add_to_valid_bitfield(ValidationTypes *val, int vbit_idx)
{
	switch (val->size) {
	case UINT_8T:
		val->value.ui8 |= (0x01 << vbit_idx);
		break;
	case UINT_16T:
		val->value.ui16 |= (0x01 << vbit_idx);
		break;
	case UINT_32T:
		val->value.ui32 |= (0x01 << vbit_idx);
		break;
	case UINT_64T:
		val->value.ui64 |= (0x01 << vbit_idx);
		break;
	default:
		printf("IR to CPER: Unknown validation bits size passed, Enum IntType=%d",
		       val->size);
	}
}

//Converts the given IR bitfield into a standard UINT64 bitfield, with fields beginning from bit 0.
UINT64 ir_to_bitfield(json_object *ir, int num_fields, const char *names[])
{
	UINT64 result = 0x0;
	for (int i = 0; i < num_fields; i++) {
		if (json_object_get_boolean(
			    json_object_object_get(ir, names[i]))) {
			result |= (0x1 << i);
		}
	}

	return result;
}

// Filters properties based on Validation Bits.
// Refer to CPER spec for vbit_idx to be passed here.
// Overload function for 16, 32, 64b
bool isvalid_prop_to_ir(ValidationTypes *val, int vbit_idx)
{
// If the option is enabled, output invalid properties
// as well as valid ones.
#ifdef OUTPUT_ALL_PROPERTIES
	return true;
#endif //OUTPUT_ALL_PROPERTIES
	UINT64 vbit_mask = 0x01 << vbit_idx;
	switch (val->size) {
	case UINT_16T:
		return (vbit_mask & val->value.ui16);

	case UINT_32T:
		return (vbit_mask & val->value.ui32);

	case UINT_64T:
		return (vbit_mask & val->value.ui64);

	default:
		printf("CPER to IR:Unknown validation bits size passed. Enum IntType: %d",
		       val->size);
	}
	return 0;
}

void print_val(ValidationTypes *val)
{
	switch (val->size) {
	case UINT_8T:
		printf("Validation bits: %x\n", val->value.ui8);
		break;
	case UINT_16T:
		printf("Validation bits: %x\n", val->value.ui16);
		break;

	case UINT_32T:
		printf("Validation bits: %x\n", val->value.ui32);
		break;

	case UINT_64T:
		printf("Validation bits: %llx\n", val->value.ui64);
		break;

	default:
		printf("CPER to IR:Unknown validation bits size passed. Enum IntType: %d",
		       val->size);
	}
}

//Converts the given UINT64 array into a JSON IR array, given the length.
json_object *uint64_array_to_ir_array(UINT64 *array, int len)
{
	json_object *array_ir = json_object_new_array();
	for (int i = 0; i < len; i++) {
		json_object_array_add(array_ir,
				      json_object_new_uint64(array[i]));
	}
	return array_ir;
}

//Converts a single UINT16 revision number into JSON IR representation.
json_object *revision_to_ir(UINT16 revision)
{
	json_object *revision_info = json_object_new_object();
	json_object_object_add(revision_info, "major",
			       json_object_new_int(revision >> 8));
	json_object_object_add(revision_info, "minor",
			       json_object_new_int(revision & 0xFF));
	return revision_info;
}

//Returns the appropriate string for the given integer severity.
const char *severity_to_string(UINT32 severity)
{
	return severity < 4 ? CPER_SEVERITY_TYPES[severity] : "Unknown";
}

//Converts a single EFI timestamp to string, at the given output.
//Output must be at least TIMESTAMP_LENGTH bytes long.
int timestamp_to_string(char *out, int out_len, EFI_ERROR_TIME_STAMP *timestamp)
{
	//Cannot go to three digits.
	int century = bcd_to_int(timestamp->Century) % 100;
	if (century >= 100) {
		return -1;
	}
	int year = bcd_to_int(timestamp->Year) % 100;
	if (year >= 100) {
		return -1;
	}
	int month = bcd_to_int(timestamp->Month);
	if (month > 12) {
		return -1;
	}
	int day = bcd_to_int(timestamp->Day);
	if (day > 31) {
		return -1;
	}
	int hours = bcd_to_int(timestamp->Hours);
	if (hours >= 24) {
		return -1;
	}
	int minutes = bcd_to_int(timestamp->Minutes);
	if (minutes > 60) {
		return -1;
	}
	int seconds = bcd_to_int(timestamp->Seconds);
	if (seconds >= 60) {
		return -1;
	}
	int written = snprintf(
		out, out_len,
		"%02hhu%02hhu-%02hhu-%02hhuT%02hhu:%02hhu:%02hhu+00:00",
		century, year, month, day, hours, minutes, seconds);

	if (written < 0 || written >= out_len) {
		printf("Timestamp buffer of insufficient size\n");
		return -1;
	}
	return 0;
}

//Converts a single timestamp string to an EFI timestamp.
void string_to_timestamp(EFI_ERROR_TIME_STAMP *out, const char *timestamp)
{
	//Ignore invalid timestamps.
	if (timestamp == NULL) {
		return;
	}

	sscanf(timestamp, "%2hhu%2hhu-%hhu-%hhuT%hhu:%hhu:%hhu+00:00",
	       &out->Century, &out->Year, &out->Month, &out->Day, &out->Hours,
	       &out->Minutes, &out->Seconds);

	//Convert back to BCD.
	out->Century = int_to_bcd(out->Century);
	out->Year = int_to_bcd(out->Year);
	out->Month = int_to_bcd(out->Month);
	out->Day = int_to_bcd(out->Day);
	out->Hours = int_to_bcd(out->Hours);
	out->Minutes = int_to_bcd(out->Minutes);
	out->Seconds = int_to_bcd(out->Seconds);
}

//Helper function to convert an EDK EFI GUID into a string for intermediate use.
int guid_to_string(char *out, size_t out_len, EFI_GUID *guid)
{
	size_t len = snprintf(
		out, out_len,
		"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid->Data1,
		guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1],
		guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5],
		guid->Data4[6], guid->Data4[7]);
	if (len != out_len) {
		return -1;
	}
	return len;
}

//Helper function to convert a string into an EDK EFI GUID.
void string_to_guid(EFI_GUID *out, const char *guid)
{
	//Ignore invalid GUIDs.
	if (guid == NULL) {
		return;
	}

	sscanf(guid,
	       "%08x-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
	       &out->Data1, &out->Data2, &out->Data3, out->Data4,
	       out->Data4 + 1, out->Data4 + 2, out->Data4 + 3, out->Data4 + 4,
	       out->Data4 + 5, out->Data4 + 6, out->Data4 + 7);
}

//Returns one if two EFI GUIDs are equal, zero otherwise.
int guid_equal(EFI_GUID *a, EFI_GUID *b)
{
	//Check top base 3 components.
	if (a->Data1 != b->Data1 || a->Data2 != b->Data2 ||
	    a->Data3 != b->Data3) {
		return 0;
	}

	//Check Data4 array for equality.
	for (int i = 0; i < 8; i++) {
		if (a->Data4[i] != b->Data4[i]) {
			return 0;
		}
	}

	return 1;
}

int select_guid_from_list(EFI_GUID *guid, EFI_GUID *guid_list[], int len)
{
	int i = 0;
	for (; i < len; i++) {
		if (guid_equal(guid, guid_list[i])) {
			break;
		}
	}
	// It's unlikely fuzzing can reliably come up with a correct guid, given how
	// much entropy there is.  If we're in fuzzing mode, and if we haven't found
	// a match, try to force a match so we get some coverage.  Note, we still
	// want coverage of the section failed to convert code, so treat index ==
	// size as section failed to convert.
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
	if (i == len) {
		i = guid->Data1 % (len + 1);
	}
#endif

	return i;
}

void add_untrusted_string(json_object *ir, const char *field_name,
			  const char *str, int len)
{
	int fru_text_len = 0;
	for (; fru_text_len < len; fru_text_len++) {
		char c = str[fru_text_len];
		if (c < 0) {
			fru_text_len = -1;
			break;
		}
		if (c == '\0') {
			break;
		}
	}
	if (fru_text_len >= 0) {
		json_object_object_add(
			ir, field_name,
			json_object_new_string_len(str, fru_text_len));
	}
}

void add_guid(json_object *ir, const char *field_name, EFI_GUID *guid)
{
	char platform_string[GUID_STRING_LENGTH + 1];
	if (!guid_to_string(platform_string, sizeof(platform_string), guid)) {
		return;
	}
	json_object_object_add(
		ir, field_name,
		json_object_new_string_len(platform_string,
					   sizeof(platform_string) - 1));
}
