/** @file

  The implementation of EFI REST Resource JSON to C structure convertor
  Protocol.

  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Protocol/RestJsonStructure.h>
#include "RestJsonStructureInternal.h"

LIST_ENTRY  mRestJsonStructureList;
EFI_HANDLE  mProtocolHandle;

/**
  This function registers Restful resource interpreter for the
  specific schema.

  @param[in]    This                     This is the EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  @param[in]    JsonStructureSupported   The type and version of REST JSON resource which this converter
                                         supports.
  @param[in]    ToStructure              The function to convert REST JSON resource to structure.
  @param[in]    ToJson                   The function to convert REST JSON structure to JSON in text format.
  @param[in]    DestroyStructure         Destroy REST JSON structure returned in ToStructure()  function.

  @retval EFI_SUCCESS             Register successfully.
  @retval Others                  Fail to register.

**/
EFI_STATUS
EFIAPI
RestJsonStructureRegister (
  IN EFI_REST_JSON_STRUCTURE_PROTOCOL           *This,
  IN EFI_REST_JSON_STRUCTURE_SUPPORTED          *JsonStructureSupported,
  IN EFI_REST_JSON_STRUCTURE_TO_STRUCTURE       ToStructure,
  IN EFI_REST_JSON_STRUCTURE_TO_JSON            ToJson,
  IN EFI_REST_JSON_STRUCTURE_DESTORY_STRUCTURE  DestroyStructure
  )
{
  UINTN                                   NumberOfNS;
  UINTN                                   Index;
  LIST_ENTRY                              *ThisList;
  REST_JSON_STRUCTURE_INSTANCE            *Instance;
  EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER  *CloneSupportedInterpId;
  EFI_REST_JSON_STRUCTURE_SUPPORTED       *ThisSupportedInterp;

  if ((This == NULL) ||
      (ToStructure == NULL) ||
      (ToJson == NULL) ||
      (DestroyStructure == NULL) ||
      (JsonStructureSupported == NULL)
      )
  {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check how many name space interpreter can interpret.
  //
  ThisList   = &JsonStructureSupported->NextSupportedRsrcInterp;
  NumberOfNS = 1;
  while (TRUE) {
    if (ThisList->ForwardLink == &JsonStructureSupported->NextSupportedRsrcInterp) {
      break;
    } else {
      ThisList = ThisList->ForwardLink;
      NumberOfNS++;
    }
  }

  DEBUG ((DEBUG_MANAGEABILITY, "%a: %d REST JSON-C interpreter(s) to register for the name spaces.\n", __func__, NumberOfNS));

  Instance =
    (REST_JSON_STRUCTURE_INSTANCE *)AllocateZeroPool (sizeof (REST_JSON_STRUCTURE_INSTANCE) + NumberOfNS * sizeof (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER));
  if (Instance == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  InitializeListHead (&Instance->NextRestJsonStructureInstance);
  Instance->NumberOfNameSpaceToConvert = NumberOfNS;
  Instance->SupportedRsrcIndentifier   = (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *)((REST_JSON_STRUCTURE_INSTANCE *)Instance + 1);
  //
  // Copy supported resource identifer interpreter.
  //
  CloneSupportedInterpId = Instance->SupportedRsrcIndentifier;
  ThisSupportedInterp    = JsonStructureSupported;
  for (Index = 0; Index < NumberOfNS; Index++) {
    CopyMem ((VOID *)CloneSupportedInterpId, (VOID *)&ThisSupportedInterp->RestResourceInterp, sizeof (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER));
    DEBUG ((DEBUG_MANAGEABILITY, "  Resource type : %a\n", ThisSupportedInterp->RestResourceInterp.NameSpace.ResourceTypeName));
    DEBUG ((DEBUG_MANAGEABILITY, "  Major version : %a\n", ThisSupportedInterp->RestResourceInterp.NameSpace.MajorVersion));
    DEBUG ((DEBUG_MANAGEABILITY, "  Minor version : %a\n", ThisSupportedInterp->RestResourceInterp.NameSpace.MinorVersion));
    DEBUG ((DEBUG_MANAGEABILITY, "  Errata version: %a\n\n", ThisSupportedInterp->RestResourceInterp.NameSpace.ErrataVersion));
    ThisSupportedInterp = (EFI_REST_JSON_STRUCTURE_SUPPORTED *)ThisSupportedInterp->NextSupportedRsrcInterp.ForwardLink;
    CloneSupportedInterpId++;
  }

  Instance->JsonToStructure  = ToStructure;
  Instance->StructureToJson  = ToJson;
  Instance->DestroyStructure = DestroyStructure;
  InsertTailList (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);
  return EFI_SUCCESS;
}

/**
  This function check if this interpreter instance support the given namesapce.

  @param[in]    This                EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  @param[in]    InterpreterInstance REST_JSON_STRUCTURE_INSTANCE
  @param[in]    RsrcTypeIdentifier  Resource type identifier.
  @param[in]    ResourceRaw         Given Restful resource.
  @param[out]   RestJSonHeader      Property interpreted from given ResourceRaw.

  @retval EFI_SUCCESS
  @retval Others.

**/
EFI_STATUS
InterpreterInstanceToStruct (
  IN EFI_REST_JSON_STRUCTURE_PROTOCOL        *This,
  IN REST_JSON_STRUCTURE_INSTANCE            *InterpreterInstance,
  IN EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER  *RsrcTypeIdentifier OPTIONAL,
  IN CHAR8                                   *ResourceRaw,
  OUT EFI_REST_JSON_STRUCTURE_HEADER         **RestJSonHeader
  )
{
  UINTN                                   Index;
  EFI_STATUS                              Status;
  EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER  *ThisSupportedRsrcTypeId;

  DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry\n", __func__));

  if ((This == NULL) ||
      (InterpreterInstance == NULL) ||
      (ResourceRaw == NULL) ||
      (RestJSonHeader == NULL)
      )
  {
    return EFI_INVALID_PARAMETER;
  }

  Status = EFI_UNSUPPORTED;
  if (RsrcTypeIdentifier == NULL) {
    //
    // No resource type identifier, send to intepreter anyway.
    // Interpreter may recognize this resource.
    //
    Status = InterpreterInstance->JsonToStructure (
                                    This,
                                    NULL,
                                    ResourceRaw,
                                    RestJSonHeader
                                    );
    if (EFI_ERROR (Status)) {
      if (Status == EFI_UNSUPPORTED) {
        DEBUG ((
          DEBUG_MANAGEABILITY,
          "%a %a.%a.%a REST JSON to C structure interpreter has no capability to interpret the resource.\n",
          InterpreterInstance->SupportedRsrcIndentifier->NameSpace.ResourceTypeName,
          InterpreterInstance->SupportedRsrcIndentifier->NameSpace.MajorVersion,
          InterpreterInstance->SupportedRsrcIndentifier->NameSpace.MinorVersion,
          InterpreterInstance->SupportedRsrcIndentifier->NameSpace.ErrataVersion
          ));
      } else {
        DEBUG ((DEBUG_MANAGEABILITY, "REST JsonToStructure returns failure - %r\n", Status));
      }
    }
  } else {
    //
    // Check if the namespace and version is supported by this interpreter.
    //
    ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier;
    for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) {
      if (AsciiStrCmp (
            RsrcTypeIdentifier->NameSpace.ResourceTypeName,
            ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName
            ) == 0)
      {
        if ((RsrcTypeIdentifier->NameSpace.MajorVersion == NULL) &&
            (RsrcTypeIdentifier->NameSpace.MinorVersion == NULL) &&
            (RsrcTypeIdentifier->NameSpace.ErrataVersion == NULL)
            )
        {
          //
          // Don't check version of this resource type identifier.
          //
          Status = InterpreterInstance->JsonToStructure (
                                          This,
                                          RsrcTypeIdentifier,
                                          ResourceRaw,
                                          RestJSonHeader
                                          );
          if (EFI_ERROR (Status)) {
            DEBUG ((DEBUG_MANAGEABILITY, "Don't check version of this resource type identifier JsonToStructure returns %r\n", Status));
            DEBUG ((DEBUG_MANAGEABILITY, "  Supported ResourceTypeName = %a\n", ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName));
          }

          break;
        } else {
          //
          // Check version.
          //
          if ((AsciiStrCmp (
                 RsrcTypeIdentifier->NameSpace.MajorVersion,
                 ThisSupportedRsrcTypeId->NameSpace.MajorVersion
                 ) == 0) &&
              (AsciiStrCmp (
                 RsrcTypeIdentifier->NameSpace.MinorVersion,
                 ThisSupportedRsrcTypeId->NameSpace.MinorVersion
                 ) == 0) &&
              (AsciiStrCmp (
                 RsrcTypeIdentifier->NameSpace.ErrataVersion,
                 ThisSupportedRsrcTypeId->NameSpace.ErrataVersion
                 ) == 0))
          {
            Status = InterpreterInstance->JsonToStructure (
                                            This,
                                            RsrcTypeIdentifier,
                                            ResourceRaw,
                                            RestJSonHeader
                                            );
            if (EFI_ERROR (Status)) {
              DEBUG ((DEBUG_MANAGEABILITY, "Check version of this resource type identifier JsonToStructure returns %r\n", Status));
              DEBUG ((DEBUG_MANAGEABILITY, "  Supported ResourceTypeName = %a\n", ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName));
              DEBUG ((DEBUG_MANAGEABILITY, "  Supported MajorVersion     = %a\n", ThisSupportedRsrcTypeId->NameSpace.MajorVersion));
              DEBUG ((DEBUG_MANAGEABILITY, "  Supported MinorVersion     = %a\n", ThisSupportedRsrcTypeId->NameSpace.MinorVersion));
              DEBUG ((DEBUG_MANAGEABILITY, "  Supported ErrataVersion    = %a\n", ThisSupportedRsrcTypeId->NameSpace.ErrataVersion));
            }

            break;
          }
        }
      }

      ThisSupportedRsrcTypeId++;
    }
  }

  return Status;
}

/**
  This function converts JSON C structure to JSON property.

  @param[in]    This                 EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  @param[in]    InterpreterInstance  REST_JSON_STRUCTURE_INSTANCE
  @param[in]    RestJSonHeader       Resource type identifier.
  @param[out]   ResourceRaw          Output in JSON text format.

  @retval EFI_SUCCESS
  @retval Others.

**/
EFI_STATUS
InterpreterEfiStructToInstance (
  IN EFI_REST_JSON_STRUCTURE_PROTOCOL  *This,
  IN REST_JSON_STRUCTURE_INSTANCE      *InterpreterInstance,
  IN EFI_REST_JSON_STRUCTURE_HEADER    *RestJSonHeader,
  OUT CHAR8                            **ResourceRaw
  )
{
  UINTN                                   Index;
  EFI_STATUS                              Status;
  EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER  *ThisSupportedRsrcTypeId;
  EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER  *RsrcTypeIdentifier;

  DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry\n", __func__));

  if ((This == NULL) ||
      (InterpreterInstance == NULL) ||
      (RestJSonHeader == NULL) ||
      (ResourceRaw == NULL)
      )
  {
    return EFI_INVALID_PARAMETER;
  }

  RsrcTypeIdentifier = &RestJSonHeader->JsonRsrcIdentifier;
  if ((RsrcTypeIdentifier == NULL) ||
      (RsrcTypeIdentifier->NameSpace.ResourceTypeName == NULL) ||
      (RsrcTypeIdentifier->NameSpace.MajorVersion == NULL) ||
      (RsrcTypeIdentifier->NameSpace.MinorVersion == NULL) ||
      (RsrcTypeIdentifier->NameSpace.ErrataVersion == NULL)
      )
  {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check if the namesapce and version is supported by this interpreter.
  //
  Status                  = EFI_UNSUPPORTED;
  ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier;
  for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) {
    if (AsciiStrCmp (
          RsrcTypeIdentifier->NameSpace.ResourceTypeName,
          ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName
          ) == 0)
    {
      //
      // Check version.
      //
      if ((AsciiStrCmp (
             RsrcTypeIdentifier->NameSpace.MajorVersion,
             ThisSupportedRsrcTypeId->NameSpace.MajorVersion
             ) == 0) &&
          (AsciiStrCmp (
             RsrcTypeIdentifier->NameSpace.MinorVersion,
             ThisSupportedRsrcTypeId->NameSpace.MinorVersion
             ) == 0) &&
          (AsciiStrCmp (
             RsrcTypeIdentifier->NameSpace.ErrataVersion,
             ThisSupportedRsrcTypeId->NameSpace.ErrataVersion
             ) == 0))
      {
        Status = InterpreterInstance->StructureToJson (
                                        This,
                                        RestJSonHeader,
                                        ResourceRaw
                                        );
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_MANAGEABILITY, "StructureToJson returns %r\n", Status));
          DEBUG ((DEBUG_MANAGEABILITY, "  Supported ResourceTypeName = %a\n", ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName));
          DEBUG ((DEBUG_MANAGEABILITY, "  Supported MajorVersion     = %a\n", ThisSupportedRsrcTypeId->NameSpace.MajorVersion));
          DEBUG ((DEBUG_MANAGEABILITY, "  Supported MinorVersion     = %a\n", ThisSupportedRsrcTypeId->NameSpace.MinorVersion));
          DEBUG ((DEBUG_MANAGEABILITY, "  Supported ErrataVersion    = %a\n", ThisSupportedRsrcTypeId->NameSpace.ErrataVersion));
        }

        break;
      }
    }

    ThisSupportedRsrcTypeId++;
  }

  return Status;
}

/**
  This function destory REST property structure.

  @param[in]    This                 EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  @param[in]    InterpreterInstance  REST_JSON_STRUCTURE_INSTANCE
  @param[in]    RestJSonHeader       Property interpreted from given ResourceRaw.

  @retval EFI_SUCCESS
  @retval Others.

**/
EFI_STATUS
InterpreterInstanceDestoryJsonStruct (
  IN EFI_REST_JSON_STRUCTURE_PROTOCOL  *This,
  IN REST_JSON_STRUCTURE_INSTANCE      *InterpreterInstance,
  IN EFI_REST_JSON_STRUCTURE_HEADER    *RestJSonHeader
  )
{
  UINTN                                   Index;
  EFI_STATUS                              Status;
  EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER  *ThisSupportedRsrcTypeId;

  if ((This == NULL) ||
      (InterpreterInstance == NULL) ||
      (RestJSonHeader == NULL)
      )
  {
    return EFI_INVALID_PARAMETER;
  }

  Status = EFI_UNSUPPORTED;
  //
  // Check if the namesapce and version is supported by this interpreter.
  //
  ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier;
  for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) {
    if (AsciiStrCmp (
          RestJSonHeader->JsonRsrcIdentifier.NameSpace.ResourceTypeName,
          ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName
          ) == 0)
    {
      if ((RestJSonHeader->JsonRsrcIdentifier.NameSpace.MajorVersion == NULL) &&
          (RestJSonHeader->JsonRsrcIdentifier.NameSpace.MinorVersion == NULL) &&
          (RestJSonHeader->JsonRsrcIdentifier.NameSpace.ErrataVersion == NULL)
          )
      {
        //
        // Don't check version of this resource type identifier.
        //
        Status = InterpreterInstance->DestroyStructure (
                                        This,
                                        RestJSonHeader
                                        );
        break;
      } else {
        //
        // Check version.
        //
        if ((AsciiStrCmp (
               RestJSonHeader->JsonRsrcIdentifier.NameSpace.MajorVersion,
               ThisSupportedRsrcTypeId->NameSpace.MajorVersion
               ) == 0) &&
            (AsciiStrCmp (
               RestJSonHeader->JsonRsrcIdentifier.NameSpace.MinorVersion,
               ThisSupportedRsrcTypeId->NameSpace.MinorVersion
               ) == 0) &&
            (AsciiStrCmp (
               RestJSonHeader->JsonRsrcIdentifier.NameSpace.ErrataVersion,
               ThisSupportedRsrcTypeId->NameSpace.ErrataVersion
               ) == 0))
        {
          Status = InterpreterInstance->DestroyStructure (
                                          This,
                                          RestJSonHeader
                                          );
          break;
        }
      }
    }

    ThisSupportedRsrcTypeId++;
  }

  return Status;
}

/**
  This function translates the given JSON text to JSON C Structure.

  @param[in]    This                EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  @param[in]    RsrcTypeIdentifier  Resource type identifier.
  @param[in]    ResourceJsonText    Given Restful resource.
  @param[out]   JsonStructure       Property interpreted from given ResourceRaw.

  @retval EFI_SUCCESS
  @retval Others.

**/
EFI_STATUS
EFIAPI
RestJsonStructureToStruct (
  IN EFI_REST_JSON_STRUCTURE_PROTOCOL        *This,
  IN EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER  *RsrcTypeIdentifier OPTIONAL,
  IN CHAR8                                   *ResourceJsonText,
  OUT EFI_REST_JSON_STRUCTURE_HEADER         **JsonStructure
  )
{
  EFI_STATUS                    Status;
  REST_JSON_STRUCTURE_INSTANCE  *Instance;

  if ((This == NULL) ||
      (ResourceJsonText == NULL) ||
      (JsonStructure == NULL)
      )
  {
    return EFI_INVALID_PARAMETER;
  }

  if (IsListEmpty (&mRestJsonStructureList)) {
    return EFI_UNSUPPORTED;
  }

  if (RsrcTypeIdentifier != NULL) {
    DEBUG ((DEBUG_MANAGEABILITY, "%a: Looking for the REST JSON to C Structure converter:\n", __func__));
    if (RsrcTypeIdentifier->NameSpace.ResourceTypeName != NULL) {
      DEBUG ((DEBUG_MANAGEABILITY, "  ResourceType: %a\n", RsrcTypeIdentifier->NameSpace.ResourceTypeName));
    } else {
      DEBUG ((DEBUG_MANAGEABILITY, "  ResourceType: NULL"));
    }

    if (RsrcTypeIdentifier->NameSpace.MajorVersion != NULL) {
      DEBUG ((DEBUG_MANAGEABILITY, "  MajorVersion: %a\n", RsrcTypeIdentifier->NameSpace.MajorVersion));
    } else {
      DEBUG ((DEBUG_MANAGEABILITY, "  MajorVersion: NULL"));
    }

    if (RsrcTypeIdentifier->NameSpace.MinorVersion != NULL) {
      DEBUG ((DEBUG_MANAGEABILITY, "  MinorVersion: %a\n", RsrcTypeIdentifier->NameSpace.MinorVersion));
    } else {
      DEBUG ((DEBUG_MANAGEABILITY, "  MinorVersion: NULL"));
    }

    if (RsrcTypeIdentifier->NameSpace.ErrataVersion != NULL) {
      DEBUG ((DEBUG_MANAGEABILITY, "  ErrataVersion: %a\n", RsrcTypeIdentifier->NameSpace.ErrataVersion));
    } else {
      DEBUG ((DEBUG_MANAGEABILITY, "  ErrataVersion: NULL"));
    }
  } else {
    DEBUG ((DEBUG_MANAGEABILITY, "%a: RsrcTypeIdentifier is given as NULL, go through all of the REST JSON to C structure interpreters.\n", __func__));
  }

  Status   = EFI_SUCCESS;
  Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList);
  while (TRUE) {
    Status = InterpreterInstanceToStruct (
               This,
               Instance,
               RsrcTypeIdentifier,
               ResourceJsonText,
               JsonStructure
               );
    if (!EFI_ERROR (Status)) {
      DEBUG ((DEBUG_MANAGEABILITY, "%a: REST JSON to C structure is interpreted successfully.\n", __func__));
      break;
    }

    if (IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) {
      DEBUG ((DEBUG_ERROR, "%a: No REST JSON to C structure interpreter found.\n", __func__));
      Status = EFI_UNSUPPORTED;
      break;
    }

    Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);
  }

  return Status;
}

/**
  This function destory REST property EFI structure which returned in
  JsonToStructure().

  @param[in]    This            EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  @param[in]    RestJSonHeader  Property to destory.

  @retval EFI_SUCCESS
  @retval Others

**/
EFI_STATUS
EFIAPI
RestJsonStructureDestroyStruct (
  IN EFI_REST_JSON_STRUCTURE_PROTOCOL  *This,
  IN EFI_REST_JSON_STRUCTURE_HEADER    *RestJSonHeader
  )
{
  EFI_STATUS                    Status;
  REST_JSON_STRUCTURE_INSTANCE  *Instance;

  if ((This == NULL) || (RestJSonHeader == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (IsListEmpty (&mRestJsonStructureList)) {
    return EFI_UNSUPPORTED;
  }

  Status   = EFI_SUCCESS;
  Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList);
  while (TRUE) {
    Status = InterpreterInstanceDestoryJsonStruct (
               This,
               Instance,
               RestJSonHeader
               );
    if (!EFI_ERROR (Status)) {
      break;
    }

    if (IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) {
      DEBUG ((DEBUG_ERROR, "%a: No REST JSON to C structure interpreter found.\n", __func__));
      Status = EFI_UNSUPPORTED;
      break;
    }

    Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);
  }

  return Status;
}

/**
  This function translates the given JSON C Structure to JSON text.

  @param[in]    This            EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  @param[in]    RestJSonHeader  Given Restful resource.
  @param[out]   ResourceRaw     Resource in RESTfuls service oriented.

  @retval EFI_SUCCESS
  @retval Others             Fail to remove the entry

**/
EFI_STATUS
EFIAPI
RestJsonStructureToJson (
  IN EFI_REST_JSON_STRUCTURE_PROTOCOL  *This,
  IN EFI_REST_JSON_STRUCTURE_HEADER    *RestJSonHeader,
  OUT CHAR8                            **ResourceRaw
  )
{
  EFI_STATUS                              Status;
  REST_JSON_STRUCTURE_INSTANCE            *Instance;
  EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER  *RsrcTypeIdentifier;

  if ((This == NULL) || (RestJSonHeader == NULL) || (ResourceRaw == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (IsListEmpty (&mRestJsonStructureList)) {
    return EFI_UNSUPPORTED;
  }

  RsrcTypeIdentifier = &RestJSonHeader->JsonRsrcIdentifier;
  DEBUG ((DEBUG_MANAGEABILITY, "Looking for the REST C Structure to JSON resource converter:\n"));
  DEBUG ((DEBUG_MANAGEABILITY, "  ResourceType : %a\n", RsrcTypeIdentifier->NameSpace.ResourceTypeName));
  DEBUG ((DEBUG_MANAGEABILITY, "  MajorVersion : %a\n", RsrcTypeIdentifier->NameSpace.MajorVersion));
  DEBUG ((DEBUG_MANAGEABILITY, "  MinorVersion : %a\n", RsrcTypeIdentifier->NameSpace.MinorVersion));
  DEBUG ((DEBUG_MANAGEABILITY, "  ErrataVersion: %a\n", RsrcTypeIdentifier->NameSpace.ErrataVersion));

  Status   = EFI_SUCCESS;
  Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList);
  while (TRUE) {
    Status = InterpreterEfiStructToInstance (
               This,
               Instance,
               RestJSonHeader,
               ResourceRaw
               );
    if (!EFI_ERROR (Status)) {
      break;
    }

    if (IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) {
      DEBUG ((DEBUG_ERROR, "%a: No REST C structure to JSON interpreter found.\n", __func__));
      Status = EFI_UNSUPPORTED;
      break;
    }

    Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);
  }

  return Status;
}

EFI_REST_JSON_STRUCTURE_PROTOCOL  mRestJsonStructureProtocol = {
  RestJsonStructureRegister,
  RestJsonStructureToStruct,
  RestJsonStructureToJson,
  RestJsonStructureDestroyStruct
};

/**
  This is the declaration of an EFI image entry point.

  @param  ImageHandle           The firmware allocated handle for the UEFI image.
  @param  SystemTable           A pointer to the EFI System Table.

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval Others                An unexpected error occurred.
**/
EFI_STATUS
EFIAPI
RestJsonStructureEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  InitializeListHead (&mRestJsonStructureList);
  //
  // Install the Restful Resource Interpreter Protocol.
  //
  mProtocolHandle = NULL;
  Status          = gBS->InstallProtocolInterface (
                           &mProtocolHandle,
                           &gEfiRestJsonStructureProtocolGuid,
                           EFI_NATIVE_INTERFACE,
                           (VOID *)&mRestJsonStructureProtocol
                           );
  return Status;
}

/**
  This is the unload handle for REST JSON to C structure module.

  Disconnect the driver specified by ImageHandle from all the devices in the handle database.
  Uninstall all the protocols installed in the driver entry point.

  @param[in] ImageHandle           The drivers' driver image.

  @retval    EFI_SUCCESS           The image is unloaded.
  @retval    Others                Failed to unload the image.

**/
EFI_STATUS
EFIAPI
RestJsonStructureUnload (
  IN EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS                    Status;
  REST_JSON_STRUCTURE_INSTANCE  *Instance;
  REST_JSON_STRUCTURE_INSTANCE  *NextInstance;

  Status = gBS->UninstallProtocolInterface (
                  mProtocolHandle,
                  &gEfiRestJsonStructureProtocolGuid,
                  (VOID *)&mRestJsonStructureProtocol
                  );

  if (IsListEmpty (&mRestJsonStructureList)) {
    return Status;
  }

  //
  // Free memory of REST_JSON_STRUCTURE_INSTANCE instance.
  //
  Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList);
  do {
    NextInstance = NULL;
    if (!IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) {
      NextInstance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);
    }

    FreePool ((VOID *)Instance);
    Instance = NextInstance;
  } while (Instance != NULL);

  return Status;
}
