/**
 * Describes high level functions for converting an entire CPER log, and functions for parsing
 * CPER headers and section descriptions into an intermediate JSON format.
 *
 * Author: Lawrence.Tang@arm.com
 **/

#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <json.h>

#include <libcper/base64.h>
#include <libcper/Cper.h>
#include <libcper/log.h>
#include <libcper/cper-parse.h>
#include <libcper/cper-parse-str.h>
#include <libcper/cper-utils.h>
#include <libcper/sections/cper-section.h>

//Private pre-definitions.
json_object *cper_header_to_ir(EFI_COMMON_ERROR_RECORD_HEADER *header);
json_object *
cper_section_descriptor_to_ir(EFI_ERROR_SECTION_DESCRIPTOR *section_descriptor);

json_object *cper_buf_section_to_ir(const void *cper_section_buf, size_t size,
				    EFI_ERROR_SECTION_DESCRIPTOR *descriptor);

json_object *cper_buf_to_ir(const unsigned char *cper_buf, size_t size)
{
	json_object *parent = NULL;
	json_object *header_ir = NULL;
	json_object *section_descriptors_ir = NULL;
	json_object *sections_ir = NULL;

	const unsigned char *pos = cper_buf;
	unsigned int remaining = size;

	if (remaining < sizeof(EFI_COMMON_ERROR_RECORD_HEADER)) {
		cper_print_log(
			"Invalid CPER file: Invalid header (incorrect signature).\n");
		goto fail;
	}

	EFI_COMMON_ERROR_RECORD_HEADER *header = NULL;
	header = (EFI_COMMON_ERROR_RECORD_HEADER *)cper_buf;
	pos += sizeof(EFI_COMMON_ERROR_RECORD_HEADER);
	remaining -= sizeof(EFI_COMMON_ERROR_RECORD_HEADER);
	if (header->SignatureStart != EFI_ERROR_RECORD_SIGNATURE_START) {
		cper_print_log(
			"Invalid CPER file: Invalid header (incorrect signature).\n");
		goto fail;
	}
	if (header->SectionCount == 0) {
		cper_print_log(
			"Invalid CPER file: Invalid section count (0).\n");
		goto fail;
	}
	if (remaining < sizeof(EFI_ERROR_SECTION_DESCRIPTOR)) {
		cper_print_log(
			"Invalid CPER file: Invalid section descriptor (section offset + length > size).\n");
		goto fail;
	}

	//Create the header JSON object from the read bytes.
	parent = json_object_new_object();
	header_ir = cper_header_to_ir(header);

	json_object_object_add(parent, "header", header_ir);

	//Read the appropriate number of section descriptors & sections, and convert them into IR format.
	section_descriptors_ir = json_object_new_array();
	sections_ir = json_object_new_array();
	for (int i = 0; i < header->SectionCount; i++) {
		//Create the section descriptor.
		if (remaining < sizeof(EFI_ERROR_SECTION_DESCRIPTOR)) {
			cper_print_log(
				"Invalid number of section headers: Header states %d sections, could not read section %d.\n",
				header->SectionCount, i + 1);
			goto fail;
		}

		EFI_ERROR_SECTION_DESCRIPTOR *section_descriptor;
		section_descriptor = (EFI_ERROR_SECTION_DESCRIPTOR *)(pos);
		pos += sizeof(EFI_ERROR_SECTION_DESCRIPTOR);
		remaining -= sizeof(EFI_ERROR_SECTION_DESCRIPTOR);

		if (section_descriptor->SectionOffset > size) {
			cper_print_log(
				"Invalid section descriptor: Section offset > size.\n");
			goto fail;
		}

		if (section_descriptor->SectionLength <= 0) {
			cper_print_log(
				"Invalid section descriptor: Section length <= 0.\n");
			goto fail;
		}

		if (section_descriptor->SectionOffset >
		    UINT_MAX - section_descriptor->SectionLength) {
			cper_print_log(
				"Invalid section descriptor: Section offset + length would overflow.\n");
			goto fail;
		}

		if (section_descriptor->SectionOffset +
			    section_descriptor->SectionLength >
		    size) {
			cper_print_log(
				"Invalid section descriptor: Section offset + length > size.\n");
			goto fail;
		}

		const unsigned char *section_begin =
			cper_buf + section_descriptor->SectionOffset;
		json_object *section_descriptor_ir =
			cper_section_descriptor_to_ir(section_descriptor);

		json_object_array_add(section_descriptors_ir,
				      section_descriptor_ir);

		//Read the section itself.
		json_object *section_ir = cper_buf_section_to_ir(
			section_begin, section_descriptor->SectionLength,
			section_descriptor);
		json_object_array_add(sections_ir, section_ir);
	}

	//Add the header, section descriptors, and sections to a parent object.
	json_object_object_add(parent, "sectionDescriptors",
			       section_descriptors_ir);
	json_object_object_add(parent, "sections", sections_ir);

	return parent;

fail:
	json_object_put(sections_ir);
	json_object_put(section_descriptors_ir);
	json_object_put(parent);
	cper_print_log("Failed to parse CPER file.\n");
	return NULL;
}

//Reads a CPER log file at the given file location, and returns an intermediate
//JSON representation of this CPER record.
json_object *cper_to_ir(FILE *cper_file)
{
	//Ensure this is really a CPER log.
	EFI_COMMON_ERROR_RECORD_HEADER header;
	if (fread(&header, sizeof(EFI_COMMON_ERROR_RECORD_HEADER), 1,
		  cper_file) != 1) {
		cper_print_log(
			"Invalid CPER file: Invalid length (log too short).\n");
		return NULL;
	}

	//Check if the header contains the magic bytes ("CPER").
	if (header.SignatureStart != EFI_ERROR_RECORD_SIGNATURE_START) {
		cper_print_log(
			"Invalid CPER file: Invalid header (incorrect signature).\n");
		return NULL;
	}
	fseek(cper_file, -sizeof(EFI_COMMON_ERROR_RECORD_HEADER), SEEK_CUR);
	unsigned char *cper_buf = malloc(header.RecordLength);
	if (fread(cper_buf, header.RecordLength, 1, cper_file) != 1) {
		cper_print_log("File read failed\n");
		free(cper_buf);
		return NULL;
	}

	json_object *ir = cper_buf_to_ir(cper_buf, header.RecordLength);
	free(cper_buf);
	return ir;
}

char *cper_to_str_ir(FILE *cper_file)
{
	json_object *jobj = cper_to_ir(cper_file);
	char *str = jobj ? strdup(json_object_to_json_string(jobj)) : NULL;

	json_object_put(jobj);
	return str;
}

char *cperbuf_to_str_ir(const unsigned char *cper, size_t size)
{
	FILE *cper_file = fmemopen((void *)cper, size, "r");

	return cper_file ? cper_to_str_ir(cper_file) : NULL;
}

//Converts a parsed CPER record header into intermediate JSON object format.
json_object *cper_header_to_ir(EFI_COMMON_ERROR_RECORD_HEADER *header)
{
	json_object *header_ir = json_object_new_object();

	//Revision/version information.
	json_object_object_add(header_ir, "revision",
			       revision_to_ir(header->Revision));

	//Section count.
	json_object_object_add(header_ir, "sectionCount",
			       json_object_new_int(header->SectionCount));

	//Error severity (with interpreted string version).
	json_object *error_severity = json_object_new_object();
	json_object_object_add(error_severity, "code",
			       json_object_new_uint64(header->ErrorSeverity));
	json_object_object_add(error_severity, "name",
			       json_object_new_string(severity_to_string(
				       header->ErrorSeverity)));
	json_object_object_add(header_ir, "severity", error_severity);

	//Total length of the record (including headers) in bytes.
	json_object_object_add(header_ir, "recordLength",
			       json_object_new_uint64(header->RecordLength));

	//If a timestamp exists according to validation bits, then add it.
	if (header->ValidationBits & 0x2) {
		char timestamp_string[TIMESTAMP_LENGTH];
		if (timestamp_to_string(timestamp_string, TIMESTAMP_LENGTH,
					&header->TimeStamp) >= 0) {
			json_object_object_add(
				header_ir, "timestamp",
				json_object_new_string(timestamp_string));

			json_object_object_add(header_ir, "timestampIsPrecise",
					       json_object_new_boolean(
						       header->TimeStamp.Flag));
		}
	}

	//If a platform ID exists according to the validation bits, then add it.
	if (header->ValidationBits & 0x1) {
		add_guid(header_ir, "platformID", &header->PlatformID);
	}

	//If a partition ID exists according to the validation bits, then add it.
	if (header->ValidationBits & 0x4) {
		add_guid(header_ir, "partitionID", &header->PartitionID);
	}

	//Creator ID of the header.
	add_guid(header_ir, "creatorID", &header->CreatorID);
	//Notification type for the header. Some defined types are available.
	json_object *notification_type = json_object_new_object();
	add_guid(notification_type, "guid", &header->NotificationType);

	//Add the human readable notification type if possible.
	const char *notification_type_readable = "Unknown";

	EFI_GUID *guids[] = {
		&gEfiEventNotificationTypeCmcGuid,
		&gEfiEventNotificationTypeCpeGuid,
		&gEfiEventNotificationTypeMceGuid,
		&gEfiEventNotificationTypePcieGuid,
		&gEfiEventNotificationTypeInitGuid,
		&gEfiEventNotificationTypeNmiGuid,
		&gEfiEventNotificationTypeBootGuid,
		&gEfiEventNotificationTypeDmarGuid,
		&gEfiEventNotificationTypeSeaGuid,
		&gEfiEventNotificationTypeSeiGuid,
		&gEfiEventNotificationTypePeiGuid,
		&gEfiEventNotificationTypeCxlGuid,
	};

	const char *readable_names[] = {
		"CMC",	"CPE",	"MCE", "PCIe", "INIT", "NMI",
		"Boot", "DMAr", "SEA", "SEI",  "PEI",  "CXL Component"
	};

	int index = select_guid_from_list(&header->NotificationType, guids,
					  sizeof(guids) / sizeof(EFI_GUID *));
	if (index < (int)(sizeof(readable_names) / sizeof(char *))) {
		notification_type_readable = readable_names[index];
	}

	json_object_object_add(
		notification_type, "type",
		json_object_new_string(notification_type_readable));
	json_object_object_add(header_ir, "notificationType",
			       notification_type);

	//The record ID for this record, unique on a given system.
	json_object_object_add(header_ir, "recordID",
			       json_object_new_uint64(header->RecordID));

	//Flag for the record, and a human readable form.
	json_object *flags = integer_to_readable_pair(
		header->Flags,
		sizeof(CPER_HEADER_FLAG_TYPES_KEYS) / sizeof(int),
		CPER_HEADER_FLAG_TYPES_KEYS, CPER_HEADER_FLAG_TYPES_VALUES,
		"Unknown");
	json_object_object_add(header_ir, "flags", flags);

	//Persistence information. Outside the scope of specification, so just a uint32 here.
	json_object_object_add(header_ir, "persistenceInfo",
			       json_object_new_uint64(header->PersistenceInfo));
	return header_ir;
}

//Converts the given EFI section descriptor into JSON IR format.
json_object *
cper_section_descriptor_to_ir(EFI_ERROR_SECTION_DESCRIPTOR *section_descriptor)
{
	json_object *section_descriptor_ir = json_object_new_object();

	//The offset of the section from the base of the record header, length.
	json_object_object_add(
		section_descriptor_ir, "sectionOffset",
		json_object_new_uint64(section_descriptor->SectionOffset));
	json_object_object_add(
		section_descriptor_ir, "sectionLength",
		json_object_new_uint64(section_descriptor->SectionLength));

	//Revision.
	json_object_object_add(section_descriptor_ir, "revision",
			       revision_to_ir(section_descriptor->Revision));

	//Flag bits.
	json_object *flags =
		bitfield_to_ir(section_descriptor->SectionFlags, 8,
			       CPER_SECTION_DESCRIPTOR_FLAGS_BITFIELD_NAMES);
	json_object_object_add(section_descriptor_ir, "flags", flags);

	//Section type (GUID).
	json_object *section_type = json_object_new_object();

	add_guid(section_type, "data", &section_descriptor->SectionType);
	//Readable section type, if possible.
	const char *section_type_readable = "Unknown";

	CPER_SECTION_DEFINITION *section =
		select_section_by_guid(&section_descriptor->SectionType);
	if (section != NULL) {
		section_type_readable = section->ReadableName;
	}

	json_object_object_add(section_type, "type",
			       json_object_new_string(section_type_readable));
	json_object_object_add(section_descriptor_ir, "sectionType",
			       section_type);

	//If validation bits indicate it exists, add FRU ID.
	if (section_descriptor->SecValidMask & 0x1) {
		add_guid(section_descriptor_ir, "fruID",
			 &section_descriptor->FruId);
	}

	//If validation bits indicate it exists, add FRU text.
	if ((section_descriptor->SecValidMask & 0x2) >> 1) {
		int fru_text_len = 0;
		for (;
		     fru_text_len < (int)sizeof(section_descriptor->FruString);
		     fru_text_len++) {
			char c = section_descriptor->FruString[fru_text_len];
			if (c < 0) {
				//cper_print_log("Fru text contains non-ASCII character\n");
				fru_text_len = -1;
				break;
			}
			if (c == '\0') {
				break;
			}
		}
		if (fru_text_len >= 0) {
			json_object_object_add(
				section_descriptor_ir, "fruText",
				json_object_new_string_len(
					section_descriptor->FruString,
					fru_text_len));
		}
	}

	//Section severity.
	json_object *section_severity = json_object_new_object();
	json_object_object_add(
		section_severity, "code",
		json_object_new_uint64(section_descriptor->Severity));
	json_object_object_add(section_severity, "name",
			       json_object_new_string(severity_to_string(
				       section_descriptor->Severity)));
	json_object_object_add(section_descriptor_ir, "severity",
			       section_severity);

	return section_descriptor_ir;
}

json_object *read_section(const unsigned char *cper_section_buf, size_t size,
			  CPER_SECTION_DEFINITION *definition)
{
	if (definition->ToIR == NULL) {
		return NULL;
	}
	json_object *section_ir = definition->ToIR(cper_section_buf, size);
	if (section_ir == NULL) {
		return NULL;
	}
	json_object *result = json_object_new_object();
	json_object_object_add(result, definition->ShortName, section_ir);
	return result;
}

CPER_SECTION_DEFINITION *select_section_by_guid(EFI_GUID *guid)
{
	size_t i = 0;
	for (; i < section_definitions_len; i++) {
		if (guid_equal(guid, section_definitions[i].Guid)) {
			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 == section_definitions_len) {
		i = guid->Data1 % (section_definitions_len + 1);
	}
#endif
	if (i < section_definitions_len) {
		return &section_definitions[i];
	}

	return NULL;
}

//Converts the section described by a single given section descriptor.
json_object *cper_buf_section_to_ir(const void *cper_section_buf, size_t size,
				    EFI_ERROR_SECTION_DESCRIPTOR *descriptor)
{
	if (descriptor->SectionLength > size) {
		cper_print_log(
			"Invalid CPER file: Invalid header (incorrect signature).\n");
		return NULL;
	}

	//Parse section to IR based on GUID.
	json_object *result = NULL;
	json_object *section_ir = NULL;

	CPER_SECTION_DEFINITION *section =
		select_section_by_guid(&descriptor->SectionType);
	if (section == NULL) {
		cper_print_log("Unknown section type guid\n");
	} else {
		result = read_section(cper_section_buf, size, section);
	}

	//Was it an unknown GUID/failed read?
	if (result == NULL) {
		//Output the data as formatted base64.
		int32_t encoded_len = 0;
		char *encoded = base64_encode(cper_section_buf,
					      descriptor->SectionLength,
					      &encoded_len);
		if (encoded == NULL) {
			cper_print_log(
				"Failed to allocate encode output buffer. \n");
		} else {
			section_ir = json_object_new_object();
			json_object_object_add(section_ir, "data",
					       json_object_new_string_len(
						       encoded, encoded_len));
			free(encoded);

			result = json_object_new_object();
			json_object_object_add(result, "Unknown", section_ir);
		}
	}
	if (result == NULL) {
		cper_print_log("RETURNING NULL!! !!\n");
	}
	return result;
}

json_object *cper_buf_single_section_to_ir(const unsigned char *cper_buf,
					   size_t size)
{
	const unsigned char *cper_end;
	const unsigned char *section_begin;
	json_object *ir;

	cper_end = cper_buf + size;

	//Read the section descriptor out.
	EFI_ERROR_SECTION_DESCRIPTOR *section_descriptor;
	if (sizeof(EFI_ERROR_SECTION_DESCRIPTOR) > size) {
		cper_print_log(
			"Size of cper buffer was too small to read section descriptor %zu\n",
			size);
		return NULL;
	}

	ir = json_object_new_object();
	section_descriptor = (EFI_ERROR_SECTION_DESCRIPTOR *)cper_buf;
	//Convert the section descriptor to IR.
	json_object *section_descriptor_ir =
		cper_section_descriptor_to_ir(section_descriptor);
	json_object_object_add(ir, "sectionDescriptor", section_descriptor_ir);
	section_begin = cper_buf + section_descriptor->SectionOffset;

	if (section_begin + section_descriptor->SectionLength >= cper_end) {
		json_object_put(ir);
		//cper_print_log("Invalid CPER file: Invalid section descriptor (section offset + length > size).\n");
		return NULL;
	}

	const unsigned char *section =
		cper_buf + section_descriptor->SectionOffset;

	//Parse the single section.
	json_object *section_ir = cper_buf_section_to_ir(
		section, section_descriptor->SectionLength, section_descriptor);
	if (section_ir == NULL) {
		cper_print_log("RETURNING NULL2!! !!\n");
	}
	json_object_object_add(ir, "section", section_ir);
	return ir;
}

//Converts a single CPER section, without a header but with a section descriptor, to JSON.
json_object *cper_single_section_to_ir(FILE *cper_section_file)
{
	json_object *ir = json_object_new_object();

	//Read the current file pointer location as base record position.
	long base_pos = ftell(cper_section_file);

	//Read the section descriptor out.
	EFI_ERROR_SECTION_DESCRIPTOR section_descriptor;
	if (fread(&section_descriptor, sizeof(EFI_ERROR_SECTION_DESCRIPTOR), 1,
		  cper_section_file) != 1) {
		cper_print_log(
			"Failed to read section descriptor for CPER single section (fread() returned an unexpected value).\n");
		json_object_put(ir);
		return NULL;
	}

	//Convert the section descriptor to IR.
	json_object *section_descriptor_ir =
		cper_section_descriptor_to_ir(&section_descriptor);
	json_object_object_add(ir, "sectionDescriptor", section_descriptor_ir);

	//Save our current position in the stream.
	long position = ftell(cper_section_file);

	//Read section as described by the section descriptor.
	fseek(cper_section_file, base_pos + section_descriptor.SectionOffset,
	      SEEK_SET);
	void *section = malloc(section_descriptor.SectionLength);
	if (fread(section, section_descriptor.SectionLength, 1,
		  cper_section_file) != 1) {
		cper_print_log(
			"Section read failed: Could not read %u bytes from global offset %d.\n",
			section_descriptor.SectionLength,
			section_descriptor.SectionOffset);
		json_object_put(ir);
		free(section);
		return NULL;
	}

	//Seek back to our original position.
	fseek(cper_section_file, position, SEEK_SET);

	//Parse the single section.
	json_object *section_ir = cper_buf_section_to_ir(
		section, section_descriptor.SectionLength, &section_descriptor);
	json_object_object_add(ir, "section", section_ir);
	free(section);
	return ir;
}

char *cperbuf_single_section_to_str_ir(const unsigned char *cper_section,
				       size_t size)
{
	json_object *jobj = cper_buf_single_section_to_ir(cper_section, size);
	char *str = jobj ? strdup(json_object_to_json_string(jobj)) : NULL;

	json_object_put(jobj);
	return str;
}
