/**
 * Describes functions for generating pseudo-random specification compliant CPER records.
 *
 * Author: Lawrence.Tang@arm.com
 **/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libcper/log.h>
#include <libcper/Cper.h>
#include <libcper/generator/gen-utils.h>
#include <libcper/generator/sections/gen-section.h>
#include <libcper/generator/cper-generate.h>

EFI_ERROR_SECTION_DESCRIPTOR *generate_section_descriptor(char *type,
							  const size_t *lengths,
							  int index,
							  int num_sections);
size_t generate_section(void **location, char *type,
			GEN_VALID_BITS_TEST_TYPE validBitsType);

//Generates a CPER record with the given section types, outputting to the given stream.
void generate_cper_record(char **types, UINT16 num_sections, FILE *out,
			  GEN_VALID_BITS_TEST_TYPE validBitsType)
{
	//Generate the sections.
	void *sections[num_sections];
	size_t section_lengths[num_sections];
	for (int i = 0; i < num_sections; i++) {
		section_lengths[i] =
			generate_section(sections + i, types[i], validBitsType);
		if (section_lengths[i] == 0) {
			//Error encountered, exit.
			printf("Error encountered generating section %d of type '%s', length returned zero.\n",
			       i + 1, types[i]);
			return;
		}
	}

	//Generate the header given the number of sections.
	EFI_COMMON_ERROR_RECORD_HEADER *header =
		(EFI_COMMON_ERROR_RECORD_HEADER *)calloc(
			1, sizeof(EFI_COMMON_ERROR_RECORD_HEADER));
	header->SignatureStart = 0x52455043; //CPER
	header->SectionCount = num_sections;
	header->SignatureEnd = 0xFFFFFFFF;
	header->Flags = 4; //HW_ERROR_FLAGS_SIMULATED
	header->RecordID = (UINT64)rand();
	header->ErrorSeverity = rand() % 4;

	//Generate a valid timestamp.
	header->TimeStamp.Century = int_to_bcd(rand() % 100);
	header->TimeStamp.Year = int_to_bcd(rand() % 100);
	header->TimeStamp.Month = int_to_bcd(rand() % 12 + 1);
	header->TimeStamp.Day = int_to_bcd(rand() % 31 + 1);
	header->TimeStamp.Hours = int_to_bcd(rand() % 24 + 1);
	header->TimeStamp.Seconds = int_to_bcd(rand() % 60);

	//Turn all validation bits on.
	header->ValidationBits = 0x3;

	//Generate the section descriptors given the number of sections.
	EFI_ERROR_SECTION_DESCRIPTOR *section_descriptors[num_sections];
	for (int i = 0; i < num_sections; i++) {
		section_descriptors[i] = generate_section_descriptor(
			types[i], section_lengths, i, num_sections);
	}

	//Calculate total length of structure, set in header.
	size_t total_len = sizeof(EFI_COMMON_ERROR_RECORD_HEADER);
	for (int i = 0; i < num_sections; i++) {
		total_len += section_lengths[i];
	}
	total_len += num_sections * sizeof(EFI_ERROR_SECTION_DESCRIPTOR);
	header->RecordLength = (UINT32)total_len;

	//Write to stream in order, free all resources.
	fwrite(header, sizeof(EFI_COMMON_ERROR_RECORD_HEADER), 1, out);
	fflush(out);
	free(header);
	for (int i = 0; i < num_sections; i++) {
		fwrite(section_descriptors[i],
		       sizeof(EFI_ERROR_SECTION_DESCRIPTOR), 1, out);
		fflush(out);
		free(section_descriptors[i]);
	}
	for (int i = 0; i < num_sections; i++) {
		fwrite(sections[i], section_lengths[i], 1, out);
		fflush(out);
		free(sections[i]);
	}
}

//Generates a single section record for the given section, and outputs to file.
void generate_single_section_record(char *type, FILE *out,
				    GEN_VALID_BITS_TEST_TYPE validBitsType)
{
	//Generate a section.
	void *section = NULL;
	size_t section_len = generate_section(&section, type, validBitsType);

	//Generate a descriptor, correct the offset.
	EFI_ERROR_SECTION_DESCRIPTOR *section_descriptor =
		generate_section_descriptor(type, &section_len, 0, 1);
	section_descriptor->SectionOffset =
		sizeof(EFI_ERROR_SECTION_DESCRIPTOR);

	//Write all to file.
	fwrite(section_descriptor, sizeof(EFI_ERROR_SECTION_DESCRIPTOR), 1,
	       out);
	fwrite(section, section_len, 1, out);
	fflush(out);

	//Free remaining resources.
	free(section_descriptor);
	free(section);
}

//Generates a single section descriptor for a section with the given properties.
EFI_ERROR_SECTION_DESCRIPTOR *generate_section_descriptor(char *type,
							  const size_t *lengths,
							  int index,
							  int num_sections)
{
	EFI_ERROR_SECTION_DESCRIPTOR *descriptor =
		(EFI_ERROR_SECTION_DESCRIPTOR *)generate_random_bytes(
			sizeof(EFI_ERROR_SECTION_DESCRIPTOR));

	//Set reserved bits to zero.
	descriptor->Resv1 = 0;
	descriptor->SectionFlags &= 0xFF;

	//Validation bits all set to 'on'.
	descriptor->SecValidMask = 0x3;

	//Set severity.
	descriptor->Severity = rand() % 4;

	//Set length, offset from base record.
	descriptor->SectionLength = (UINT32)lengths[index];
	descriptor->SectionOffset =
		sizeof(EFI_COMMON_ERROR_RECORD_HEADER) +
		(num_sections * sizeof(EFI_ERROR_SECTION_DESCRIPTOR));
	for (int i = 0; i < index; i++) {
		descriptor->SectionOffset += lengths[i];
	}

	//Ensure the FRU text is not null terminated early.
	for (int i = 0; i < 20; i++) {
		// FRU string can only be printable ASCII
		descriptor->FruString[i] = rand() % (0x7f - 0x20) + 0x20;

		//Null terminate last byte.
		if (i == 19) {
			descriptor->FruString[i] = 0x0;
		}
	}

	//If section type is not "unknown", set section type GUID based on type name.
	int section_guid_found = 0;
	if (strcmp(type, "unknown") == 0) {
		section_guid_found = 1;
	} else {
		//Find the appropriate GUID for this section name.
		for (size_t i = 0; i < generator_definitions_len; i++) {
			if (strcmp(type, generator_definitions[i].ShortName) ==
			    0) {
				memcpy(&descriptor->SectionType,
				       generator_definitions[i].Guid,
				       sizeof(EFI_GUID));
				section_guid_found = 1;
				break;
			}
		}
	}

	//Undefined section, show error.
	if (!section_guid_found) {
		//Undefined section, show error.
		printf("Undefined section type '%s' provided. See 'cper-generate --help' for command information.\n",
		       type);
		return 0;
	}

	return descriptor;
}

//Generates a single CPER section given the string type.
size_t generate_section(void **location, char *type,
			GEN_VALID_BITS_TEST_TYPE validBitsType)
{
	//The length of the section.
	size_t length = 0;

	//If the section name is "unknown", simply generate a random bytes section.
	int section_generated = 0;
	if (strcmp(type, "unknown") == 0) {
		length = generate_random_section(location, ALL_VALID);
		section_generated = 1;
	} else {
		//Function defined section, switch on the type, generate accordingly.
		for (size_t i = 0; i < generator_definitions_len; i++) {
			if (strcmp(type, generator_definitions[i].ShortName) ==
			    0) {
				length = generator_definitions[i].Generate(
					location, validBitsType);
				section_generated = 1;
				break;
			}
		}
	}

	//If we didn't find a section generator for the given name, error out.
	if (!section_generated) {
		printf("Undefined section type '%s' given to generate. See 'cper-generate --help' for command information.\n",
		       type);
		return 0;
	}

	return length;
}
