/**
 * Describes functions for converting CXL component error CPER sections from binary and JSON format
 * into an intermediate format.
 * 
 * Author: Lawrence.Tang@arm.com
 **/
#include <stdio.h>
#include "json.h"
#include "b64.h"
#include "../edk/Cper.h"
#include "../cper-utils.h"
#include "cper-section-cxl-component.h"

//Converts a single CXL component error CPER section into JSON IR.
json_object* cper_section_cxl_component_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor)
{
    EFI_CXL_COMPONENT_EVENT_HEADER* cxl_error = (EFI_CXL_COMPONENT_EVENT_HEADER*)section;
    json_object* section_ir = json_object_new_object();

    //Length (bytes) for the entire structure.
    json_object_object_add(section_ir, "length", json_object_new_uint64(cxl_error->Length));
    
    //Validation bits.
    json_object* validation = bitfield_to_ir(cxl_error->ValidBits, 3, CXL_COMPONENT_ERROR_VALID_BITFIELD_NAMES);
    json_object_object_add(section_ir, "validationBits", validation);

    //Device ID.
    json_object* device_id = json_object_new_object();
    json_object_object_add(device_id, "vendorID", json_object_new_int(cxl_error->DeviceId.VendorId));
    json_object_object_add(device_id, "deviceID", json_object_new_int(cxl_error->DeviceId.DeviceId));
    json_object_object_add(device_id, "functionNumber", json_object_new_int(cxl_error->DeviceId.FunctionNumber));
    json_object_object_add(device_id, "deviceNumber", json_object_new_int(cxl_error->DeviceId.DeviceNumber));
    json_object_object_add(device_id, "busNumber", json_object_new_int(cxl_error->DeviceId.BusNumber));
    json_object_object_add(device_id, "segmentNumber", json_object_new_int(cxl_error->DeviceId.SegmentNumber));
    json_object_object_add(device_id, "slotNumber", json_object_new_int(cxl_error->DeviceId.SlotNumber));
    json_object_object_add(section_ir, "deviceID", device_id);

    //Device serial.
    json_object_object_add(section_ir, "deviceSerial", json_object_new_uint64(cxl_error->DeviceSerial));

    //The specification for this is defined within the CXL Specification Section 8.2.9.1.
    unsigned char* cur_pos = (unsigned char*)(cxl_error + 1);
    int remaining_len = cxl_error->Length - sizeof(cxl_error);
    if (remaining_len > 0)
    {
        json_object* event_log = json_object_new_object();
        char* encoded = b64_encode(cur_pos, remaining_len);
        json_object_object_add(event_log, "data", json_object_new_string(encoded));
        free(encoded);
        json_object_object_add(section_ir, "cxlComponentEventLog", event_log);
    }

    return section_ir;
}

//Converts a single given CXL Component CPER-JSON section into CPER binary, outputting to the
//given stream.
void ir_section_cxl_component_to_cper(json_object* section, FILE* out)
{
    EFI_CXL_COMPONENT_EVENT_HEADER* section_cper =
        (EFI_CXL_COMPONENT_EVENT_HEADER*)calloc(1, sizeof(EFI_CXL_COMPONENT_EVENT_HEADER));

    //Length of the structure.
    section_cper->Length = json_object_get_uint64(json_object_object_get(section, "length"));

    //Validation bits.
    section_cper->ValidBits = ir_to_bitfield(json_object_object_get(section, "validationBits"), 
        3, CXL_COMPONENT_ERROR_VALID_BITFIELD_NAMES);

    //Device ID information.
    json_object* device_id = json_object_object_get(section, "deviceID");
    section_cper->DeviceId.VendorId = json_object_get_uint64(json_object_object_get(device_id, "vendorID"));
    section_cper->DeviceId.DeviceId = json_object_get_uint64(json_object_object_get(device_id, "deviceID"));
    section_cper->DeviceId.FunctionNumber = 
        json_object_get_uint64(json_object_object_get(device_id, "functionNumber"));
    section_cper->DeviceId.DeviceNumber = 
        json_object_get_uint64(json_object_object_get(device_id, "deviceNumber"));
    section_cper->DeviceId.BusNumber = 
        json_object_get_uint64(json_object_object_get(device_id, "busNumber"));
    section_cper->DeviceId.SegmentNumber = 
        json_object_get_uint64(json_object_object_get(device_id, "segmentNumber"));
    section_cper->DeviceId.SlotNumber = 
        json_object_get_uint64(json_object_object_get(device_id, "slotNumber"));

    //Device serial number.
    section_cper->DeviceSerial = json_object_get_uint64(json_object_object_get(section, "deviceSerial"));

    //Write header out to stream.
    fwrite(section_cper, sizeof(EFI_CXL_COMPONENT_EVENT_HEADER), 1, out);
    fflush(out);

    //CXL component event log, decoded from base64.
    json_object* event_log = json_object_object_get(section, "cxlComponentEventLog");
    json_object* encoded = json_object_object_get(event_log, "data");
    int log_length = section_cper->Length - sizeof(EFI_CXL_COMPONENT_EVENT_HEADER);
    char* decoded = b64_decode(json_object_get_string(encoded), json_object_get_string_len(encoded));
    fwrite(decoded, log_length, 1, out);
    fflush(out);
    free(decoded);

    free(section_cper);
}