/**
 * Describes functions for converting processor-generic CPER sections from binary and JSON format
 * into an intermediate format.
 *
 * Author: Lawrence.Tang@arm.com
 **/

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

//Converts the given processor-generic CPER section into JSON IR.
json_object *cper_section_generic_to_ir(void *section)
{
	EFI_PROCESSOR_GENERIC_ERROR_DATA *section_generic =
		(EFI_PROCESSOR_GENERIC_ERROR_DATA *)section;
	json_object *section_ir = json_object_new_object();

	//Validation bits.
	json_object *validation =
		bitfield_to_ir(section_generic->ValidFields, 13,
			       GENERIC_VALIDATION_BITFIELD_NAMES);
	json_object_object_add(section_ir, "validationBits", validation);

	//Processor type, with human readable name if possible.
	json_object *processor_type = integer_to_readable_pair(
		section_generic->Type,
		sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int),
		GENERIC_PROC_TYPES_KEYS, GENERIC_PROC_TYPES_VALUES,
		"Unknown (Reserved)");
	json_object_object_add(section_ir, "processorType", processor_type);

	//Processor ISA, with human readable name if possible.
	json_object *processor_isa = integer_to_readable_pair(
		section_generic->Isa,
		sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int),
		GENERIC_ISA_TYPES_KEYS, GENERIC_ISA_TYPES_VALUES,
		"Unknown (Reserved)");
	json_object_object_add(section_ir, "processorISA", processor_isa);

	//Processor error type, with human readable name if possible.
	json_object *processor_error_type = integer_to_readable_pair(
		section_generic->ErrorType,
		sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int),
		GENERIC_ERROR_TYPES_KEYS, GENERIC_ERROR_TYPES_VALUES,
		"Unknown (Reserved)");
	json_object_object_add(section_ir, "errorType", processor_error_type);

	//The operation performed, with a human readable name if possible.
	json_object *operation = integer_to_readable_pair(
		section_generic->Operation,
		sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int),
		GENERIC_OPERATION_TYPES_KEYS, GENERIC_OPERATION_TYPES_VALUES,
		"Unknown (Reserved)");
	json_object_object_add(section_ir, "operation", operation);

	//Flags, additional information about the error.
	json_object *flags = bitfield_to_ir(section_generic->Flags, 4,
					    GENERIC_FLAGS_BITFIELD_NAMES);
	json_object_object_add(section_ir, "flags", flags);

	//The level of the error.
	json_object_object_add(section_ir, "level",
			       json_object_new_int(section_generic->Level));

	//CPU version information.
	json_object_object_add(
		section_ir, "cpuVersionInfo",
		json_object_new_uint64(section_generic->VersionInfo));

	//CPU brand string. May not exist if on ARM.
	json_object_object_add(
		section_ir, "cpuBrandString",
		json_object_new_string(section_generic->BrandString));

	//Remaining 64-bit fields.
	json_object_object_add(section_ir, "processorID",
			       json_object_new_uint64(section_generic->ApicId));
	json_object_object_add(
		section_ir, "targetAddress",
		json_object_new_uint64(section_generic->TargetAddr));
	json_object_object_add(
		section_ir, "requestorID",
		json_object_new_uint64(section_generic->RequestorId));
	json_object_object_add(
		section_ir, "responderID",
		json_object_new_uint64(section_generic->ResponderId));
	json_object_object_add(
		section_ir, "instructionIP",
		json_object_new_uint64(section_generic->InstructionIP));

	return section_ir;
}

//Converts the given CPER-JSON processor-generic error section into CPER binary,
//outputting to the provided stream.
void ir_section_generic_to_cper(json_object *section, FILE *out)
{
	EFI_PROCESSOR_GENERIC_ERROR_DATA *section_cper =
		(EFI_PROCESSOR_GENERIC_ERROR_DATA *)calloc(
			1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA));

	//Validation bits.
	section_cper->ValidFields = ir_to_bitfield(
		json_object_object_get(section, "validationBits"), 13,
		GENERIC_VALIDATION_BITFIELD_NAMES);

	//Various name/value pair fields.
	section_cper->Type = (UINT8)readable_pair_to_integer(
		json_object_object_get(section, "processorType"));
	section_cper->Isa = (UINT8)readable_pair_to_integer(
		json_object_object_get(section, "processorISA"));
	section_cper->ErrorType = (UINT8)readable_pair_to_integer(
		json_object_object_get(section, "errorType"));
	section_cper->Operation = (UINT8)readable_pair_to_integer(
		json_object_object_get(section, "operation"));

	//Flags.
	section_cper->Flags =
		(UINT8)ir_to_bitfield(json_object_object_get(section, "flags"),
				      4, GENERIC_FLAGS_BITFIELD_NAMES);

	//Various numeric/string fields.
	section_cper->Level = (UINT8)json_object_get_int(
		json_object_object_get(section, "level"));
	section_cper->VersionInfo = json_object_get_uint64(
		json_object_object_get(section, "cpuVersionInfo"));
	section_cper->ApicId = json_object_get_uint64(
		json_object_object_get(section, "processorID"));
	section_cper->TargetAddr = json_object_get_uint64(
		json_object_object_get(section, "targetAddress"));
	section_cper->RequestorId = json_object_get_uint64(
		json_object_object_get(section, "requestorID"));
	section_cper->ResponderId = json_object_get_uint64(
		json_object_object_get(section, "responderID"));
	section_cper->InstructionIP = json_object_get_uint64(
		json_object_object_get(section, "instructionIP"));

	//CPU brand string.
	const char *brand_string = json_object_get_string(
		json_object_object_get(section, "cpuBrandString"));
	if (brand_string != NULL) {
		strncpy(section_cper->BrandString, brand_string,
			sizeof(section_cper->BrandString) - 1);
		section_cper
			->BrandString[sizeof(section_cper->BrandString) - 1] =
			'\0';
	}

	//Write & flush out to file, free memory.
	fwrite(section_cper, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA), 1, out);
	fflush(out);
	free(section_cper);
}
