/** @file
  The implementation of EDKII Redfish Platform Config Protocol.

  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
  Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/
#include "RedfishPlatformConfigDxe.h"
#include "RedfishPlatformConfigImpl.h"

extern REDFISH_PLATFORM_CONFIG_PRIVATE  *mRedfishPlatformConfigPrivate;

/**
  Debug dump HII string.

  @param[in]  HiiHandle   HII handle instance
  @param[in]  StringId    HII string to dump

  @retval EFI_SUCCESS       Dump HII string successfully
  @retval Others            Errors occur

**/
EFI_STATUS
DumpHiiString (
  IN EFI_HII_HANDLE  HiiHandle,
  IN EFI_STRING_ID   StringId
  )
{
  EFI_STRING  String;

  if ((HiiHandle == NULL) || (StringId == 0)) {
    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "???"));
    return EFI_INVALID_PARAMETER;
  }

  String = HiiGetString (HiiHandle, StringId, NULL);
  if (String == NULL) {
    return EFI_NOT_FOUND;
  }

  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%s", String));
  FreePool (String);

  return EFI_SUCCESS;
}

/**
  Debug dump HII form-set data.

  @param[in]  FormsetPrivate    HII form-set private instance.

  @retval EFI_SUCCESS       Dump form-set successfully
  @retval Others            Errors occur

**/
EFI_STATUS
DumpFormset (
  IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate
  )
{
  LIST_ENTRY                                 *HiiFormLink;
  LIST_ENTRY                                 *HiiNextFormLink;
  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE       *HiiFormPrivate;
  LIST_ENTRY                                 *HiiStatementLink;
  LIST_ENTRY                                 *HiiNextStatementLink;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *HiiStatementPrivate;
  UINTN                                      Index;

  if (FormsetPrivate == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Index       = 0;
  HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
  while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
    HiiFormPrivate  = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
    HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);

    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  [%d] form: %d title: ", ++Index, HiiFormPrivate->Id));
    DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));

    HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
    while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
      HiiStatementPrivate  = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
      HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);

      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "    QID: 0x%x Prompt: ", HiiStatementPrivate->QuestionId));
      DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate->Description);
      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));

      HiiStatementLink = HiiNextStatementLink;
    }

    HiiFormLink = HiiNextFormLink;
  }

  return EFI_SUCCESS;
}

/**
  Debug dump HII form-set list.

  @param[in]  FormsetList   Form-set list instance

  @retval EFI_SUCCESS       Dump list successfully
  @retval Others            Errors occur

**/
EFI_STATUS
DumpFormsetList (
  IN  LIST_ENTRY  *FormsetList
  )
{
  LIST_ENTRY                                *HiiFormsetLink;
  LIST_ENTRY                                *HiiFormsetNextLink;
  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
  UINTN                                     Index;

  if (FormsetList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (IsListEmpty (FormsetList)) {
    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Empty formset list\n", __func__));
    return EFI_SUCCESS;
  }

  Index          = 0;
  HiiFormsetLink = GetFirstNode (FormsetList);
  while (!IsNull (FormsetList, HiiFormsetLink)) {
    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
    HiiFormsetPrivate  = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);

    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
    DumpFormset (HiiFormsetPrivate);

    HiiFormsetLink = HiiFormsetNextLink;
  }

  return EFI_SUCCESS;
}

/**
  Return the HII string length. We don't check word alignment
  of the input string as same as the checking in StrLen
  function, because the HII string in the database is compact
  at the byte alignment.

  @param[in]  String  Input UCS format string.

  @retval Length of the string.

**/
UINTN
EFIAPI
HiiStrLen (
  IN  CONST CHAR16  *String
  )
{
  UINTN  Length;

  ASSERT (String != NULL);

  for (Length = 0; *String != L'\0'; String++, Length++) {
  }

  return Length;
}

/**
  Return the HII string size. We don't check word alignment
  of the input string as same as the checking in StrLen
  function, because the HII string in the database is compact
  at the byte alignment.

  @param[in]  String  Input UCS format string.

  @retval Size of the string.

**/
UINTN
EFIAPI
HiiStrSize (
  IN      CONST CHAR16  *String
  )
{
  return (HiiStrLen (String) + 1) * sizeof (*String);
}

/**
  Compare two HII strings. We don't check word alignment
  of the input string as same as the checking in StrLen
  function, because the HII string in the database is compact
  at the byte alignment.

  @param[in]  FirstString   Input UCS format of string to search.
  @param[in]  SecondString  Input UCS format of string to look for in
                            FirstString;

  @retval 0   The strings are identical.
          !0  The strings are not identical.

**/
INTN
EFIAPI
HiiStrCmp (
  IN      CONST CHAR16  *FirstString,
  IN      CONST CHAR16  *SecondString
  )
{
  //
  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
  //
  ASSERT (HiiStrSize (FirstString) != 0);
  ASSERT (HiiStrSize (SecondString) != 0);

  while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
    FirstString++;
    SecondString++;
  }

  return *FirstString - *SecondString;
}

/**
  Delete a string from HII Package List by given HiiHandle.

  @param[in]  StringId           Id of the string in HII database.
  @param[in]  HiiHandle          The HII package list handle.

  @retval EFI_SUCCESS            The string was deleted successfully.
  @retval EFI_INVALID_PARAMETER  StringId is zero.

**/
EFI_STATUS
HiiDeleteString (
  IN  EFI_STRING_ID   StringId,
  IN  EFI_HII_HANDLE  HiiHandle
  )
{
  CHAR16  NullChar;

  if (StringId == 0x00) {
    return EFI_INVALID_PARAMETER;
  }

  NullChar = CHAR_NULL;
  HiiSetString (HiiHandle, StringId, &NullChar, NULL);

  return EFI_SUCCESS;
}

/**
  Retrieves a unicode string from a string package in a given language. The
  returned string is allocated using AllocatePool().  The caller is responsible
  for freeing the allocated buffer using FreePool().

  If HiiHandle is NULL, then ASSERT().
  If StringId is 0, then ASSET.

  @param[in]  HiiHandle         A handle that was previously registered in the HII Database.
  @param[in]  Language          The specified configure language to get string.
  @param[in]  StringId          The identifier of the string to retrieved from the string
                                package associated with HiiHandle.

  @retval NULL   The string specified by StringId is not present in the string package.
  @retval Other  The string was returned.

**/
EFI_STRING
HiiGetRedfishString (
  IN EFI_HII_HANDLE  HiiHandle,
  IN CHAR8           *Language,
  IN EFI_STRING_ID   StringId
  )
{
  EFI_STATUS  Status;
  UINTN       StringSize;
  CHAR16      TempString;
  EFI_STRING  String;

  if ((mRedfishPlatformConfigPrivate->HiiString == NULL) || (HiiHandle == NULL) || (StringId == 0) || IS_EMPTY_STRING (Language)) {
    ASSERT (FALSE);
    return NULL;
  }

  //
  // Retrieve the size of the string in the string package for the BestLanguage
  //
  StringSize = 0;
  Status     = mRedfishPlatformConfigPrivate->HiiString->GetString (
                                                           mRedfishPlatformConfigPrivate->HiiString,
                                                           Language,
                                                           HiiHandle,
                                                           StringId,
                                                           &TempString,
                                                           &StringSize,
                                                           NULL
                                                           );
  //
  // If GetString() returns EFI_SUCCESS for a zero size,
  // then there are no supported languages registered for HiiHandle.  If GetString()
  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
  // in the HII Database
  //
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return NULL;
  }

  //
  // Allocate a buffer for the return string
  //
  String = AllocateZeroPool (StringSize);
  if (String == NULL) {
    return NULL;
  }

  //
  // Retrieve the string from the string package
  //
  Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
                                                       mRedfishPlatformConfigPrivate->HiiString,
                                                       Language,
                                                       HiiHandle,
                                                       StringId,
                                                       String,
                                                       &StringSize,
                                                       NULL
                                                       );
  if (EFI_ERROR (Status)) {
    //
    // Free the buffer and return NULL if the supported languages can not be retrieved.
    //
    FreePool (String);
    String = NULL;
  }

  //
  // Return the Null-terminated Unicode string
  //
  return String;
}

/**
  Retrieves a ASCII string from a string package in a given language. The
  returned string is allocated using AllocatePool().  The caller is responsible
  for freeing the allocated buffer using FreePool().

  If HiiHandle is NULL, then ASSERT().
  If StringId is 0, then ASSET.

  @param[in]  HiiHandle         A handle that was previously registered in the HII Database.
  @param[in]  Language          The specified configure language to get string.
  @param[in]  StringId          The identifier of the string to retrieved from the string
                                package associated with HiiHandle.

  @retval NULL   The string specified by StringId is not present in the string package.
  @retval Other  The string was returned.

**/
CHAR8 *
HiiGetRedfishAsciiString (
  IN EFI_HII_HANDLE  HiiHandle,
  IN CHAR8           *Language,
  IN EFI_STRING_ID   StringId
  )
{
  EFI_STRING  HiiString;
  CHAR8       *AsciiString;

  HiiString = HiiGetRedfishString (HiiHandle, Language, StringId);
  if (HiiString == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: Can not find string ID: 0x%x with %a\n", __func__, StringId, Language));
    return NULL;
  }

  AsciiString = StrToAsciiStr (HiiString);
  FreePool (HiiString);

  return AsciiString;
}

/**
  Get ASCII string from HII database in English language. The returned string is allocated
  using AllocatePool(). The caller is responsible for freeing the allocated buffer using
  FreePool().

  @param[in]  HiiHandle         A handle that was previously registered in the HII Database.
  @param[in]  StringId          The identifier of the string to retrieved from the string
                                package associated with HiiHandle.

  @retval NULL   The string specified by StringId is not present in the string package.
  @retval Other  The string was returned.

**/
CHAR8 *
HiiGetEnglishAsciiString (
  IN EFI_HII_HANDLE  HiiHandle,
  IN EFI_STRING_ID   StringId
  )
{
  EFI_STRING  HiiString;
  CHAR8       *AsciiString;

  HiiString = HiiGetRedfishString (HiiHandle, ENGLISH_LANGUAGE_CODE, StringId);
  if (HiiString == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: Can not find string ID: 0x%x with %a\n", __func__, StringId, ENGLISH_LANGUAGE_CODE));
    return NULL;
  }

  AsciiString = StrToAsciiStr (HiiString);
  FreePool (HiiString);

  return AsciiString;
}

/**
  Check and see if this is supported schema or not.

  @param[in]  SupportedSchema   The list of supported schema.
  @param[in]  Schema            Schema string to be checked.

  @retval BOOLEAN               TRUE if this is supported schema. FALSE otherwise.

**/
BOOLEAN
CheckSupportedSchema (
  IN REDFISH_PLATFORM_CONFIG_SCHEMA  *SupportedSchema,
  IN CHAR8                           *Schema
  )
{
  UINTN  Index;

  if ((SupportedSchema == NULL) || IS_EMPTY_STRING (Schema)) {
    return FALSE;
  }

  if (SupportedSchema->Count == 0) {
    return FALSE;
  }

  for (Index = 0; Index < SupportedSchema->Count; Index++) {
    if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 0) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Get the list of supported schema from the given HII handle.

  @param[in]  HiiHandle         HII handle instance.
  @param[out] SupportedSchema   Supported schema on this HII handle.

  @retval EFI_SUCCESS           Schema list is returned.
  @retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema is NULL.
  @retval EFI_NOT_FOUND         No supported schema found.
  @retval EFI_OUT_OF_RESOURCES  System is out of memory.

**/
EFI_STATUS
GetSupportedSchema (
  IN  EFI_HII_HANDLE                  HiiHandle,
  OUT REDFISH_PLATFORM_CONFIG_SCHEMA  *SupportedSchema
  )
{
  CHAR8  *SupportedLanguages;
  UINTN  Index;
  UINTN  LangIndex;
  UINTN  Count;
  UINTN  StrSize;
  UINTN  ListIndex;

  if ((HiiHandle == NULL) || (SupportedSchema == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  SupportedSchema->Count = 0;

  SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
  if (SupportedLanguages == NULL) {
    return EFI_NOT_FOUND;
  }

  Index     = 0;
  LangIndex = 0;
  Count     = 0;
  while (TRUE) {
    if ((SupportedLanguages[Index] == ';') || (SupportedLanguages[Index] == '\0')) {
      if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
        ++Count;
      }

      LangIndex = Index + 1;
    }

    if (SupportedLanguages[Index] == '\0') {
      break;
    }

    ++Index;
  }

  if (Count == 0) {
    FreePool (SupportedLanguages);

    return EFI_NOT_FOUND;
  }

  SupportedSchema->Count      = Count;
  SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
  if (SupportedSchema->SchemaList == NULL) {
    FreePool (SupportedLanguages);

    return EFI_OUT_OF_RESOURCES;
  }

  Index     = 0;
  LangIndex = 0;
  ListIndex = 0;
  while (TRUE) {
    if ((SupportedLanguages[Index] == ';') || (SupportedLanguages[Index] == '\0')) {
      if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
        StrSize                                         = Index - LangIndex;
        SupportedSchema->SchemaList[ListIndex]          = AllocateCopyPool ((StrSize + 1), &SupportedLanguages[LangIndex]);
        SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
        ++ListIndex;
      }

      LangIndex = Index + 1;
    }

    if (SupportedLanguages[Index] == '\0') {
      break;
    }

    ++Index;
  }

  FreePool (SupportedLanguages);

  return EFI_SUCCESS;
}

/**
  Search and find statement private instance by given regular expression pattern
  which describes the Configure Language.

  @param[in]  RegularExpressionProtocol   Regular express protocol.
  @param[in]  FormsetList                 Form-set list to search.
  @param[in]  Schema                      Schema to be matched.
  @param[in]  Pattern                     Regular expression pattern.
  @param[out] StatementList               Statement list that match above pattern.

  @retval EFI_SUCCESS             Statement list is returned.
  @retval EFI_INVALID_PARAMETER   Input parameter is NULL.
  @retval EFI_NOT_READY           Regular express protocol is NULL.
  @retval EFI_NOT_FOUND           No statement is found.
  @retval EFI_OUT_OF_RESOURCES    System is out of memory.

**/
EFI_STATUS
GetStatementPrivateByConfigureLangRegex (
  IN  EFI_REGULAR_EXPRESSION_PROTOCOL                 *RegularExpressionProtocol,
  IN  LIST_ENTRY                                      *FormsetList,
  IN  CHAR8                                           *Schema,
  IN  EFI_STRING                                      Pattern,
  OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST  *StatementList
  )
{
  LIST_ENTRY                                     *HiiFormsetLink;
  LIST_ENTRY                                     *HiiFormsetNextLink;
  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE       *HiiFormsetPrivate;
  LIST_ENTRY                                     *HiiFormLink;
  LIST_ENTRY                                     *HiiNextFormLink;
  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE           *HiiFormPrivate;
  LIST_ENTRY                                     *HiiStatementLink;
  LIST_ENTRY                                     *HiiNextStatementLink;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE      *HiiStatementPrivate;
  EFI_STRING                                     TmpString;
  UINTN                                          CaptureCount;
  BOOLEAN                                        IsMatch;
  EFI_STATUS                                     Status;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF  *StatementRef;

  if ((FormsetList == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Pattern) || (StatementList == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (RegularExpressionProtocol == NULL) {
    return EFI_NOT_READY;
  }

  StatementList->Count = 0;
  InitializeListHead (&StatementList->StatementList);

  if (IsListEmpty (FormsetList)) {
    return EFI_NOT_FOUND;
  }

  HiiFormsetLink = GetFirstNode (FormsetList);
  while (!IsNull (FormsetList, HiiFormsetLink)) {
    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
    HiiFormsetPrivate  = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);

    //
    // Performance check.
    // If there is no desired Redfish schema found, skip this formset.
    //
    if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema)) {
      HiiFormsetLink = HiiFormsetNextLink;
      continue;
    }

    HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
    while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
      HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);
      HiiFormPrivate  = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);

      HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
      while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
        HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
        HiiStatementPrivate  = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);

        if ((HiiStatementPrivate->Description != 0) &&
            (RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED) || !HiiStatementPrivate->Suppressed))
        {
          TmpString = HiiStatementPrivate->XuefiRedfishStr;
          if (TmpString != NULL) {
            Status = RegularExpressionProtocol->MatchString (
                                                  RegularExpressionProtocol,
                                                  TmpString,
                                                  Pattern,
                                                  &gEfiRegexSyntaxTypePerlGuid,
                                                  &IsMatch,
                                                  NULL,
                                                  &CaptureCount
                                                  );
            if (EFI_ERROR (Status)) {
              DEBUG ((DEBUG_ERROR, "%a: MatchString \"%s\" failed: %r\n", __func__, Pattern, Status));
              ASSERT (FALSE);
              return Status;
            }

            //
            // Found
            //
            if (IsMatch) {
              StatementRef = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
              if (StatementRef == NULL) {
                return EFI_OUT_OF_RESOURCES;
              }

              StatementRef->Statement = HiiStatementPrivate;
              InsertTailList (&StatementList->StatementList, &StatementRef->Link);
              ++StatementList->Count;
            }
          } else {
            if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
              DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->XuefiRedfishStr is NULL, x-UEFI-string has something wrong.\n", __func__));
              ASSERT (FALSE);
            }
          }
        }

        HiiStatementLink = HiiNextStatementLink;
      }

      HiiFormLink = HiiNextFormLink;
    }

    HiiFormsetLink = HiiFormsetNextLink;
  }

  return EFI_SUCCESS;
}

/**
  Get statement private instance by the given configure language.

  @param[in]  FormsetList                 Form-set list to search.
  @param[in]  Schema                      Schema to be matched.
  @param[in]  ConfigureLang               Configure language.

  @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *   Pointer to statement private instance.

**/
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
GetStatementPrivateByConfigureLang (
  IN  LIST_ENTRY  *FormsetList,
  IN  CHAR8       *Schema,
  IN  EFI_STRING  ConfigureLang
  )
{
  LIST_ENTRY                                 *HiiFormsetLink;
  LIST_ENTRY                                 *HiiFormsetNextLink;
  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE   *HiiFormsetPrivate;
  LIST_ENTRY                                 *HiiFormLink;
  LIST_ENTRY                                 *HiiNextFormLink;
  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE       *HiiFormPrivate;
  LIST_ENTRY                                 *HiiStatementLink;
  LIST_ENTRY                                 *HiiNextStatementLink;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *HiiStatementPrivate;
  EFI_STRING                                 TmpString;
  UINTN                                      Index;

  if ((FormsetList == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang)) {
    return NULL;
  }

  if (IsListEmpty (FormsetList)) {
    return NULL;
  }

  Index          = 0;
  HiiFormsetLink = GetFirstNode (FormsetList);
  while (!IsNull (FormsetList, HiiFormsetLink)) {
    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
    HiiFormsetPrivate  = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);

    //
    // Performance check.
    // If there is no desired Redfish schema found, skip this formset.
    //
    if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema)) {
      HiiFormsetLink = HiiFormsetNextLink;
      continue;
    }

    HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
    while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
      HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);
      HiiFormPrivate  = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);

      HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
      while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
        HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
        HiiStatementPrivate  = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);

        if ((HiiStatementPrivate->Description != 0) &&
            (RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED) || !HiiStatementPrivate->Suppressed))
        {
          TmpString = HiiStatementPrivate->XuefiRedfishStr;
          if (TmpString != NULL) {
            Index++;
            DEBUG_REDFISH_THIS_MODULE (
              REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_SEARCH,
              "%a: [%d] check %s in QID: 0x%x form: 0x%x formset: %g\n",
              __func__,
              Index,
              ConfigureLang,
              HiiStatementPrivate->QuestionId,
              HiiFormPrivate->Id,
              &HiiFormsetPrivate->Guid
              );
            if (HiiStrCmp (TmpString, ConfigureLang) == 0) {
              return HiiStatementPrivate;
            }
          } else {
            if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
              DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->XuefiRedfishStr is NULL, x-UEFI-string has something wrong.\n", __func__));
              ASSERT (FALSE);
            }
          }
        }

        HiiStatementLink = HiiNextStatementLink;
      }

      HiiFormLink = HiiNextFormLink;
    }

    HiiFormsetLink = HiiFormsetNextLink;
  }

  return NULL;
}

/**
  Get form-set private instance by the given HII handle.

  @param[in]  HiiHandle       HII handle instance.
  @param[in]  FormsetList     Form-set list to search.

  @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *   Pointer to form-set private instance.

**/
REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
GetFormsetPrivateByHiiHandle (
  IN  EFI_HII_HANDLE  HiiHandle,
  IN  LIST_ENTRY      *FormsetList
  )
{
  LIST_ENTRY                                *HiiFormsetLink;
  LIST_ENTRY                                *HiiFormsetNextLink;
  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;

  if ((HiiHandle == NULL) || (FormsetList == NULL)) {
    return NULL;
  }

  if (IsListEmpty (FormsetList)) {
    return NULL;
  }

  HiiFormsetLink = GetFirstNode (FormsetList);
  while (!IsNull (FormsetList, HiiFormsetLink)) {
    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
    HiiFormsetPrivate  = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);

    if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
      return HiiFormsetPrivate;
    }

    HiiFormsetLink = HiiFormsetNextLink;
  }

  return NULL;
}

/**
  Release x-UEFI-string related information.

  @param[in]      FormsetPrivate Pointer to HII form-set private instance.

  @retval         EFI_STATUS

**/
EFI_STATUS
ReleaseXuefiStringDatabase (
  IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate
  )
{
  REDFISH_X_UEFI_STRING_DATABASE  *ThisDatabase;
  REDFISH_X_UEFI_STRING_DATABASE  *PreDatabase;
  REDFISH_X_UEFI_STRINGS_ARRAY    *ThisStringArray;
  REDFISH_X_UEFI_STRINGS_ARRAY    *PreStringArray;
  BOOLEAN                         EndDatabase;
  BOOLEAN                         EndArray;

  if (FormsetPrivate->HiiPackageListHeader != NULL) {
    FreePool (FormsetPrivate->HiiPackageListHeader);
  }

  // Walk through x-UEFI-redfish string database.
  if (!IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
    EndDatabase  = FALSE;
    ThisDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&FormsetPrivate->XuefiRedfishStringDatabase);
    while (!EndDatabase) {
      // Walk through string arrays.
      if (!IsListEmpty (&ThisDatabase->XuefiRedfishStringArrays)) {
        EndArray        = FALSE;
        ThisStringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&ThisDatabase->XuefiRedfishStringArrays);
        while (!EndArray) {
          // Remove this array
          FreePool (ThisStringArray->ArrayEntryAddress);
          EndArray       = IsNodeAtEnd (&ThisDatabase->XuefiRedfishStringArrays, &ThisStringArray->NextArray);
          PreStringArray = ThisStringArray;
          if (!EndArray) {
            ThisStringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&ThisDatabase->XuefiRedfishStringArrays, &ThisStringArray->NextArray);
          }

          RemoveEntryList (&PreStringArray->NextArray);
          FreePool (PreStringArray);
        }
      }

      //
      // Remove this database
      //
      EndDatabase = IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &ThisDatabase->NextXuefiRedfishLanguage);
      PreDatabase = ThisDatabase;
      if (!EndDatabase) {
        ThisDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (&FormsetPrivate->XuefiRedfishStringDatabase, &ThisDatabase->NextXuefiRedfishLanguage);
      }

      RemoveEntryList (&PreDatabase->NextXuefiRedfishLanguage);
      FreePool (PreDatabase);
    }
  }

  return EFI_SUCCESS;
}

/**
  Release formset and all the forms and statements that belong to this formset.

  @param[in]      FormsetPrivate Pointer to HII form-set private instance.

  @retval         EFI_STATUS

**/
EFI_STATUS
ReleaseFormset (
  IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate
  )
{
  LIST_ENTRY                                 *HiiFormLink;
  LIST_ENTRY                                 *HiiNextFormLink;
  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE       *HiiFormPrivate;
  LIST_ENTRY                                 *HiiStatementLink;
  LIST_ENTRY                                 *HiiNextStatementLink;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *HiiStatementPrivate;
  UINTN                                      Index;

  if (FormsetPrivate == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
  while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
    HiiFormPrivate  = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
    HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);

    HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
    while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
      HiiStatementPrivate  = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
      HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);

      //
      // HiiStatementPrivate->HiiStatement will be released in DestroyFormSet().
      //
      RemoveEntryList (&HiiStatementPrivate->Link);
      FreePool (HiiStatementPrivate);
      HiiStatementLink = HiiNextStatementLink;
    }

    //
    // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
    //

    RemoveEntryList (&HiiFormPrivate->Link);
    FreePool (HiiFormPrivate);
    HiiFormLink = HiiNextFormLink;
  }

  if (FormsetPrivate->HiiFormSet != NULL) {
    DestroyFormSet (FormsetPrivate->HiiFormSet);
    FormsetPrivate->HiiFormSet = NULL;
  }

  if (FormsetPrivate->DevicePathStr != NULL) {
    FreePool (FormsetPrivate->DevicePathStr);
  }

  //
  // Release schema list
  //
  if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
    for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count; Index++) {
      FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
    }

    FreePool (FormsetPrivate->SupportedSchema.SchemaList);
    FormsetPrivate->SupportedSchema.SchemaList = NULL;
    FormsetPrivate->SupportedSchema.Count      = 0;
  }

  ReleaseXuefiStringDatabase (FormsetPrivate);

  return EFI_SUCCESS;
}

/**
  Create new form-set instance.

  @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *   Pointer to newly created form-set private instance.

**/
REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *
NewFormsetPrivate (
  VOID
  )
{
  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *NewFormsetPrivate;

  NewFormsetPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
  if (NewFormsetPrivate == NULL) {
    return NULL;
  }

  //
  // Initial newly created formset private data.
  //
  InitializeListHead (&NewFormsetPrivate->HiiFormList);
  InitializeListHead (&NewFormsetPrivate->XuefiRedfishStringDatabase);

  return NewFormsetPrivate;
}

/**
  Create new x-UEFI-redfish string array.

  @param[in]      XuefiRedfishStringDatabase  The x-UEFI-redfish string database.

  @retval         EFI_OUT_OF_RESOURCES  Not enough memory for creating a new array.
                  EFI_SUCCESS           New array is created successfully.

**/
EFI_STATUS
NewRedfishXuefiStringArray (
  IN  REDFISH_X_UEFI_STRING_DATABASE  *XuefiRedfishStringDatabase
  )
{
  REDFISH_X_UEFI_STRINGS_ARRAY  *ArrayAddress;

  // Initial first REDFISH_X_UEFI_STRINGS_ARRAY memory.
  ArrayAddress = (REDFISH_X_UEFI_STRINGS_ARRAY *)AllocateZeroPool (sizeof (REDFISH_X_UEFI_STRINGS_ARRAY));
  if (ArrayAddress == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: Failed to allocate REDFISH_X_UEFI_STRINGS_ARRAY.\n", __func__));
    return EFI_OUT_OF_RESOURCES;
  }

  InitializeListHead (&ArrayAddress->NextArray);

  // Allocate memory buffer for REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT elements.
  ArrayAddress->ArrayEntryAddress = \
    (REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT *)AllocateZeroPool (sizeof (REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT) * X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER);
  if (ArrayAddress->ArrayEntryAddress == NULL) {
    FreePool (ArrayAddress);
    DEBUG ((DEBUG_ERROR, "%a: Failed to allocate array for REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENTs.\n", __func__));
    return EFI_OUT_OF_RESOURCES;
  }

  XuefiRedfishStringDatabase->StringsArrayBlocks++;
  InsertTailList (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &ArrayAddress->NextArray);
  return EFI_SUCCESS;
}

/**
  Get the pointer of x-UEFI-redfish database or create a new database.

  @param[in]      FormsetPrivate          Pointer to HII form-set private instance.
  @param[in]      HiiStringPackageHeader  HII string package header.

  @retval         Pointer to REDFISH_X_UEFI_STRING_DATABASE.
                  If NULL, it fails to obtain x-UEFI-redfish database.

**/
REDFISH_X_UEFI_STRING_DATABASE *
GetExistOrCreateXuefiStringDatabase (
  IN  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
  IN  EFI_HII_STRING_PACKAGE_HDR                *HiiStringPackageHeader
  )
{
  EFI_STATUS                      Status;
  BOOLEAN                         CreateNewOne;
  REDFISH_X_UEFI_STRING_DATABASE  *XuefiRedfishStringDatabase;

  CreateNewOne               = TRUE;
  XuefiRedfishStringDatabase = NULL;
  if (!IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
    XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&FormsetPrivate->XuefiRedfishStringDatabase);

    while (TRUE) {
      if (AsciiStriCmp (XuefiRedfishStringDatabase->XuefiRedfishLanguage, HiiStringPackageHeader->Language) == 0) {
        CreateNewOne = FALSE;
        break;
      }

      if (IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage)) {
        break;
      }

      XuefiRedfishStringDatabase = \
        (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage);
    }
  }

  if (CreateNewOne) {
    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  Creating x-UEFI-redfish (%a) string database...\n", HiiStringPackageHeader->Language));
    XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)AllocateZeroPool (sizeof (REDFISH_X_UEFI_STRING_DATABASE));
    if (XuefiRedfishStringDatabase == NULL) {
      DEBUG ((DEBUG_ERROR, "  Failed to allocate REDFISH_X_UEFI_STRING_DATABASE.\n"));
      return NULL;
    }

    InitializeListHead (&XuefiRedfishStringDatabase->NextXuefiRedfishLanguage);
    InitializeListHead (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays);
    XuefiRedfishStringDatabase->StringsArrayBlocks   = 0;
    XuefiRedfishStringDatabase->XuefiRedfishLanguage = HiiStringPackageHeader->Language;

    Status = NewRedfishXuefiStringArray (XuefiRedfishStringDatabase);
    if (EFI_ERROR (Status)) {
      FreePool (XuefiRedfishStringDatabase);
      return NULL;
    }

    DEBUG ((
      DEBUG_REDFISH_PLATFORM_CONFIG,
      "  x-UEFI-redfish (%a):\n    String array is added to XuefiRedfishStringDatabase, total %d arrays now.\n",
      XuefiRedfishStringDatabase->XuefiRedfishLanguage,
      XuefiRedfishStringDatabase->StringsArrayBlocks
      ));

    // Link string database to FormsetPrivate.
    InsertTailList (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage);
  }

  return XuefiRedfishStringDatabase;
}

/**
  Check and allocate a new x-UEFI-redfish array if it is insufficient for the
  newly added x-UEFI-redfish string.

  @param[in]      FormsetPrivate              Pointer to HII form-set private instance.
  @param[in]      XuefiRedfishStringDatabase  Pointer to the x-UEFI-redfish database.
  @param[in]      StringId                    String ID added to database.

  @retval         EFI_SUCCESS                 The size of x-UEFI-string array is adjusted or
                                              is not required to be adjusted.
                  Otherwise, refer to the error code returned from NewRedfishXuefiStringArray().

**/
EFI_STATUS
RedfishXuefiStringAdjustArrays (
  IN  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
  IN  REDFISH_X_UEFI_STRING_DATABASE            *XuefiRedfishStringDatabase,
  IN  EFI_STRING_ID                             StringId
  )
{
  EFI_STATUS  Status;

  while (((StringId + X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) / X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) > (UINT16)XuefiRedfishStringDatabase->StringsArrayBlocks) {
    Status = NewRedfishXuefiStringArray (XuefiRedfishStringDatabase);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a: Failed to adjust x-UEFI-string array", __func__));
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/**
  Insert a x-UEFI-redfish string to database.

  @param[in]      FormsetPrivate          Pointer to HII form-set private instance.
  @param[in]      HiiStringPackageHeader  Pointer to HII string package.
  @param[in]      StringId                The HII string ID
  @param[in]      StringTextPtr           Pointer to HII string text.

  @retval         EFI_SUCCESS             The HII string is added to database.
                  EFI_LOAD_ERROR          Something wrong when insert an HII string
                                          to database.

**/
EFI_STATUS
RedfishXuefiStringInsertDatabase (
  IN  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
  IN  EFI_HII_STRING_PACKAGE_HDR                *HiiStringPackageHeader,
  IN  EFI_STRING_ID                             StringId,
  IN  CHAR16                                    *StringTextPtr
  )
{
  EFI_STATUS                      Status;
  UINTN                           StringIdOffset;
  REDFISH_X_UEFI_STRING_DATABASE  *XuefiRedfishStringDatabase;
  REDFISH_X_UEFI_STRINGS_ARRAY    *ThisArray;

  XuefiRedfishStringDatabase = GetExistOrCreateXuefiStringDatabase (FormsetPrivate, HiiStringPackageHeader);
  if (XuefiRedfishStringDatabase == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: Failed to get REDFISH_X_UEFI_STRING_DATABASE of x-UEFI-redfish language %a.\n", __func__, HiiStringPackageHeader->Language));
    ReleaseXuefiStringDatabase (FormsetPrivate);
    return EFI_LOAD_ERROR;
  }

  Status = RedfishXuefiStringAdjustArrays (FormsetPrivate, XuefiRedfishStringDatabase, StringId);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Failed to adjust x-UEFI-redfish string array.\n", __func__));
    ReleaseXuefiStringDatabase (FormsetPrivate);
    return EFI_LOAD_ERROR;
  }

  // Insert string to x-UEFI-redfish string array.
  StringIdOffset = (UINTN)StringId;
  ThisArray      = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays);
  while (StringIdOffset >= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) {
    ThisArray       = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &ThisArray->NextArray);
    StringIdOffset -= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER;
  }

  // Insert string
  (ThisArray->ArrayEntryAddress + StringIdOffset)->StringId  = StringId;
  (ThisArray->ArrayEntryAddress + StringIdOffset)->UcsString = StringTextPtr;

  DEBUG_REDFISH_THIS_MODULE (
    REDFISH_PLATFORM_CONFIG_DEBUG_STRING_DATABASE,
    "  Insert string ID: (%d) to database\n    x-UEFI-string: \"%s\"\n    Language: %a.\n",
    StringId,
    StringTextPtr,
    HiiStringPackageHeader->Language
    );
  return EFI_SUCCESS;
}

/**
  Get x-UEFI-redfish string and language by string ID.

  @param[in]       FormsetPrivate          Pointer to HII form-set private instance.
  @param[in]       HiiStringPackageHeader  HII string package header.
  @param[out]      TotalStringAdded        Return the total strings added to database.

  @retval  TRUE   x-UEFI-redfish string and ID map is inserted to database.
           FALSE  Something is wrong when insert x-UEFI-redfish string and ID map.

**/
BOOLEAN
CreateXuefiLanguageStringIdMap (
  IN   REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
  IN   EFI_HII_STRING_PACKAGE_HDR                *HiiStringPackageHeader,
  OUT  UINTN                                     *TotalStringAdded
  )
{
  EFI_STATUS               Status;
  UINT8                    *BlockHdr;
  EFI_STRING_ID            CurrentStringId;
  UINTN                    BlockSize;
  UINTN                    Index;
  UINT8                    *StringTextPtr;
  UINTN                    Offset;
  UINT16                   StringCount;
  UINT16                   SkipCount;
  UINT8                    Length8;
  EFI_HII_SIBT_EXT2_BLOCK  Ext2;
  UINT32                   Length32;
  UINT8                    *StringBlockInfo;
  UINTN                    StringsAdded;

  StringsAdded = 0;

  //
  // Parse the string blocks to get the string text and font.
  //
  StringBlockInfo = (UINT8 *)((UINTN)HiiStringPackageHeader + HiiStringPackageHeader->StringInfoOffset);
  BlockHdr        = StringBlockInfo;
  BlockSize       = 0;
  Offset          = 0;
  CurrentStringId = 1;
  while (*BlockHdr != EFI_HII_SIBT_END) {
    switch (*BlockHdr) {
      case EFI_HII_SIBT_STRING_SCSU:
        Offset        = sizeof (EFI_HII_STRING_BLOCK);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRING_SCSU_FONT:
        Offset        = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRINGS_SCSU:
        CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
        StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8));
        BlockSize    += StringTextPtr - BlockHdr;

        for (Index = 0; Index < StringCount; Index++) {
          BlockSize    += AsciiStrSize ((CHAR8 *)StringTextPtr);
          StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_STRINGS_SCSU_FONT:
        CopyMem (
          &StringCount,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT16)
          );
        StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8));
        BlockSize    += StringTextPtr - BlockHdr;

        for (Index = 0; Index < StringCount; Index++) {
          BlockSize    += AsciiStrSize ((CHAR8 *)StringTextPtr);
          StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_STRING_UCS2:
        Offset        = sizeof (EFI_HII_STRING_BLOCK);
        StringTextPtr = BlockHdr + Offset;

        // x-UEFI-redfish string is always encoded as UCS and started with '/'.
        if (*StringTextPtr == (UINT16)'/') {
          Status = RedfishXuefiStringInsertDatabase (
                     FormsetPrivate,
                     HiiStringPackageHeader,
                     CurrentStringId,
                     (CHAR16 *)StringTextPtr
                     );
          if (EFI_ERROR (Status)) {
            DEBUG ((DEBUG_ERROR, "%a: Failed to insert x-UEFI-redfish string %s.\n", __func__, StringTextPtr));
            return FALSE;
          }

          StringsAdded++;
        }

        BlockSize += (Offset + HiiStrSize ((CHAR16 *)StringTextPtr));
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRING_UCS2_FONT:
        Offset        = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK)  - sizeof (CHAR16);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += (Offset + HiiStrSize ((CHAR16 *)StringTextPtr));
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRINGS_UCS2:
        Offset        = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset;
        CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
        for (Index = 0; Index < StringCount; Index++) {
          BlockSize    += HiiStrSize ((CHAR16 *)StringTextPtr);
          StringTextPtr = StringTextPtr + HiiStrSize ((CHAR16 *)StringTextPtr);
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_STRINGS_UCS2_FONT:
        Offset        = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset;
        CopyMem (
          &StringCount,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT16)
          );
        for (Index = 0; Index < StringCount; Index++) {
          BlockSize    += HiiStrSize ((CHAR16 *)StringTextPtr);
          StringTextPtr = StringTextPtr + HiiStrSize ((CHAR16 *)StringTextPtr);
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_DUPLICATE:
        BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_SKIP1:
        SkipCount       = (UINT16)(*(UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
        CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
        BlockSize      +=  sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
        break;

      case EFI_HII_SIBT_SKIP2:
        CopyMem (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
        CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
        BlockSize      +=  sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
        break;

      case EFI_HII_SIBT_EXT1:
        CopyMem (
          &Length8,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT8)
          );
        BlockSize += Length8;
        break;

      case EFI_HII_SIBT_EXT2:
        CopyMem (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
        BlockSize += Ext2.Length;
        break;

      case EFI_HII_SIBT_EXT4:
        CopyMem (
          &Length32,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT32)
          );

        BlockSize += Length32;
        break;

      default:
        break;
    }

    BlockHdr = (UINT8 *)(StringBlockInfo + BlockSize);
  }

  *TotalStringAdded = StringsAdded;
  return TRUE;
}

/**
  Get x-UEFI-redfish string and language by string ID.

  @param[in]      FormsetPrivate       Pointer to HII form-set private instance.
  @param[in]      StringId             The HII string ID.
  @param[out]     String               Optionally return USC string.
  @param[out]     Language             Optionally return x-UEFI-redfish language.
  @param[out]     XuefiStringDatabase  Optionally return x-UEFI-redfish database.

  @retval  EFI_SUCCESS            String information is returned.
           EFI_INVALID_PARAMETER  One of the given parameters to this function is
                                  invalid.
           EFI_NOT_FOUND          String is not found.

**/
EFI_STATUS
GetXuefiStringAndLangByStringId (
  IN   REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
  IN   EFI_STRING_ID                             StringId,
  OUT  CHAR16                                    **String OPTIONAL,
  OUT  CHAR8                                     **Language OPTIONAL,
  OUT  REDFISH_X_UEFI_STRING_DATABASE            **XuefiStringDatabase OPTIONAL
  )
{
  REDFISH_X_UEFI_STRING_DATABASE  *XuefiRedfishStringDatabase;
  REDFISH_X_UEFI_STRINGS_ARRAY    *StringArray;
  UINT16                          StringIndex;

  if ((String == NULL) && (Language == NULL) && (XuefiStringDatabase == NULL)) {
    DEBUG ((DEBUG_ERROR, "%a: Invalid parameters for this function.\n", __func__));
    return EFI_INVALID_PARAMETER;
  }

  if (IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
    return EFI_NOT_FOUND;
  }

  XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&FormsetPrivate->XuefiRedfishStringDatabase);
  while (TRUE) {
    if (Language != NULL) {
      *Language = XuefiRedfishStringDatabase->XuefiRedfishLanguage;
    }

    StringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays);

    // Loop to the correct string array.
    StringIndex = StringId;
    while (StringIndex >= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) {
      if (IsNodeAtEnd (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &StringArray->NextArray)) {
        goto ErrorExit;
      }

      StringArray  = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &StringArray->NextArray);
      StringIndex -= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER;
    }

    //
    // NOTE: The string ID in the formset is a unique number.
    //       If the string in the array is NULL, then the matched string ID
    //       should be in another x-UEFI-redfish database.
    //
    if ((StringArray->ArrayEntryAddress + StringIndex)->UcsString != NULL) {
      //
      // String ID is belong to this x-uef-redfish language database.
      //
      if (String != NULL) {
        *String = (StringArray->ArrayEntryAddress + StringIndex)->UcsString;
      }

      if (XuefiStringDatabase != NULL) {
        *XuefiStringDatabase = XuefiRedfishStringDatabase;
      }

      return EFI_SUCCESS;
    }

    if (IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage)) {
      return EFI_NOT_FOUND;
    }

    XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (
                                                                     &FormsetPrivate->XuefiRedfishStringDatabase,
                                                                     &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage
                                                                     );
  }

ErrorExit:;
  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: String ID (%d) is not in any x-uef-redfish string databases.\n", __func__, StringId));
  return EFI_NOT_FOUND;
}

/**
  Build a x-UEFI-redfish database for the newly added x-UEFI-redfish language.

  @param[in]      FormsetPrivate          Pointer to HII form-set private instance.

**/
VOID
BuildXUefiRedfishStringDatabase (
  IN  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate
  )
{
  EFI_STATUS                  Status;
  UINTN                       BufferSize;
  EFI_HII_PACKAGE_HEADER      *PackageHeader;
  UINTN                       EndingPackageAddress;
  EFI_HII_STRING_PACKAGE_HDR  *HiiStringPackageHeader;
  UINTN                       SupportedSchemaLangCount;
  CHAR8                       **SupportedSchemaLang;
  BOOLEAN                     StringIdMapIsBuilt;
  UINTN                       TotalStringsAdded;
  UINTN                       NumberPackageStrings;

  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Building x-UEFI-redfish string database, HII Formset GUID - %g.\n", __func__, &FormsetPrivate->Guid));

  BufferSize = 0;
  Status     = mRedfishPlatformConfigPrivate->HiiDatabase->ExportPackageLists (
                                                             mRedfishPlatformConfigPrivate->HiiDatabase,
                                                             FormsetPrivate->HiiHandle,
                                                             &BufferSize,
                                                             FormsetPrivate->HiiPackageListHeader
                                                             );
  if (Status != EFI_BUFFER_TOO_SMALL) {
    DEBUG ((DEBUG_ERROR, "  Failed to export package list.\n"));
    return;
  }

  FormsetPrivate->HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)AllocateZeroPool (BufferSize);
  if (FormsetPrivate->HiiPackageListHeader == NULL) {
    DEBUG ((DEBUG_ERROR, "  Failed to allocate memory for the exported package list.\n"));
    return;
  }

  Status = mRedfishPlatformConfigPrivate->HiiDatabase->ExportPackageLists (
                                                         mRedfishPlatformConfigPrivate->HiiDatabase,
                                                         FormsetPrivate->HiiHandle,
                                                         &BufferSize,
                                                         FormsetPrivate->HiiPackageListHeader
                                                         );
  if (EFI_ERROR (Status)) {
    FreePool (FormsetPrivate->HiiPackageListHeader);
    FormsetPrivate->HiiPackageListHeader = NULL;
    return;
  }

  TotalStringsAdded = 0;
  //
  // Finding the string package.
  //
  EndingPackageAddress = (UINTN)FormsetPrivate->HiiPackageListHeader + FormsetPrivate->HiiPackageListHeader->PackageLength;
  PackageHeader        = (EFI_HII_PACKAGE_HEADER *)(FormsetPrivate->HiiPackageListHeader + 1);
  SupportedSchemaLang  = FormsetPrivate->SupportedSchema.SchemaList;
  while ((UINTN)PackageHeader < EndingPackageAddress) {
    switch (PackageHeader->Type) {
      case EFI_HII_PACKAGE_STRINGS:
        StringIdMapIsBuilt     = FALSE;
        HiiStringPackageHeader = (EFI_HII_STRING_PACKAGE_HDR *)PackageHeader;

        // Check if this is the string package for x-UEFI-redfish
        for (SupportedSchemaLangCount = 0;
             SupportedSchemaLangCount < FormsetPrivate->SupportedSchema.Count;
             SupportedSchemaLangCount++
             )
        {
          if (AsciiStrnCmp (
                *(SupportedSchemaLang + SupportedSchemaLangCount),
                HiiStringPackageHeader->Language,
                AsciiStrLen (HiiStringPackageHeader->Language)
                ) == 0)
          {
            StringIdMapIsBuilt = CreateXuefiLanguageStringIdMap (FormsetPrivate, HiiStringPackageHeader, &NumberPackageStrings);
            if (StringIdMapIsBuilt) {
              TotalStringsAdded += NumberPackageStrings;
            }

            break;
          }
        }

        if (StringIdMapIsBuilt == FALSE) {
          if (AsciiStrStr (HiiStringPackageHeader->Language, X_UEFI_SCHEMA_PREFIX) == NULL) {
            DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  No need to build x-UEFI-redfish string ID map for HII language %a\n", HiiStringPackageHeader->Language));
          } else {
            DEBUG ((DEBUG_ERROR, "  Failed to build x-UEFI-redfish string ID map of HII language %a\n", HiiStringPackageHeader->Language));
          }
        }

      default:
        PackageHeader = (EFI_HII_PACKAGE_HEADER *)((UINTN)PackageHeader + PackageHeader->Length);
    }
  }

  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  Total %d x-UEFI-redfish config language are added.\n", TotalStringsAdded));
}

/**
  Load the HII formset from the given HII handle.

  @param[in]  HiiHandle       Target HII handle to load.
  @param[out] FormsetPrivate  The formset private data.

  @retval EFI_STATUS          The formset is loaded successfully.
  @retval EFI_UNSUPPORTED     This formset doesn't have any x-UEFI-redfish configuration.

**/
EFI_STATUS
LoadFormset (
  IN  EFI_HII_HANDLE                            HiiHandle,
  OUT REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate
  )
{
  EFI_STATUS                                 Status;
  HII_FORMSET                                *HiiFormSet;
  HII_FORM                                   *HiiForm;
  LIST_ENTRY                                 *HiiFormLink;
  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE       *HiiFormPrivate;
  HII_STATEMENT                              *HiiStatement;
  LIST_ENTRY                                 *HiiStatementLink;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *HiiStatementPrivate;
  EFI_GUID                                   ZeroGuid;
  EXPRESS_RESULT                             ExpressionResult;
  CHAR16                                     *String;

  if ((HiiHandle == NULL) || (FormsetPrivate == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
  if (HiiFormSet == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: No memory resource for HII_FORMSET - %g\n", __func__, FormsetPrivate->Guid));
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Find HII formset by the given HII handle.
  //
  ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
  Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
  if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
    DEBUG ((DEBUG_ERROR, "%a: Formset not found by HII handle - %g\n", __func__, FormsetPrivate->Guid));
    Status = EFI_NOT_FOUND;
    goto ErrorExit;
  }

  //
  // Initialize formset
  //
  InitializeFormSet (HiiFormSet);

  //
  // Initialize formset private data.
  //
  FormsetPrivate->HiiFormSet = HiiFormSet;
  FormsetPrivate->HiiHandle  = HiiHandle;
  CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
  FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet->DevicePath, FALSE, FALSE);
  Status                        = GetSupportedSchema (FormsetPrivate->HiiHandle, &FormsetPrivate->SupportedSchema);
  if (EFI_ERROR (Status)) {
    if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: No x-UEFI-redfish configuration found on the formset - %g\n", __func__, &FormsetPrivate->Guid));
      //
      // If there is no x-UEFI-redfish language in this form-set, we don't add formset
      // since we don't need to build menu path for attribute registry.
      //
      return EFI_UNSUPPORTED;
    }
  } else {
    // Building x-UEFI-redfish string database
    BuildXUefiRedfishStringDatabase (FormsetPrivate);
  }

  HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
  while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
    HiiForm = HII_FORM_FROM_LINK (HiiFormLink);

    HiiFormPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
    if (HiiFormPrivate == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      DEBUG ((DEBUG_ERROR, "%a: No memory resource for REDFISH_PLATFORM_CONFIG_FORM_PRIVATE.\n", __func__));
      goto ErrorExit;
    }

    //
    // Initialize form private data.
    //
    HiiFormPrivate->HiiForm       = HiiForm;
    HiiFormPrivate->Id            = HiiForm->FormId;
    HiiFormPrivate->Title         = HiiForm->FormTitle;
    HiiFormPrivate->ParentFormset = FormsetPrivate;
    HiiFormPrivate->Suppressed    = FALSE;
    InitializeListHead (&HiiFormPrivate->StatementList);

    if ((HiiForm->SuppressExpression != NULL) &&
        (EvaluateExpressionList (HiiForm->SuppressExpression, TRUE, HiiFormSet, HiiForm) == ExpressSuppress))
    {
      HiiFormPrivate->Suppressed = TRUE;
    }

    HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
    while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
      HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);

      HiiStatementPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
      if (HiiStatementPrivate == NULL) {
        DEBUG ((DEBUG_ERROR, "%a: No memory resource for REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE.\n", __func__));
        Status = EFI_OUT_OF_RESOURCES;
        goto ErrorExit;
      }

      //
      // Initialize statement private data.
      //
      HiiStatementPrivate->HiiStatement             = HiiStatement;
      HiiStatementPrivate->QuestionId               = HiiStatement->QuestionId;
      HiiStatementPrivate->Description              = HiiStatement->Prompt;
      HiiStatementPrivate->Help                     = HiiStatement->Help;
      HiiStatementPrivate->ParentForm               = HiiFormPrivate;
      HiiStatementPrivate->Flags                    = HiiStatement->QuestionFlags;
      HiiStatementPrivate->StatementData.NumMaximum = HiiStatement->ExtraData.NumData.Maximum;
      HiiStatementPrivate->StatementData.NumMinimum = HiiStatement->ExtraData.NumData.Minimum;
      HiiStatementPrivate->StatementData.NumStep    = HiiStatement->ExtraData.NumData.Step;
      HiiStatementPrivate->StatementData.StrMaxSize = HiiStatement->ExtraData.StrData.MaxSize;
      HiiStatementPrivate->StatementData.StrMinSize = HiiStatement->ExtraData.StrData.MinSize;
      HiiStatementPrivate->Suppressed               = FALSE;
      HiiStatementPrivate->GrayedOut                = FALSE;

      //
      // Expression
      //
      if (HiiFormPrivate->Suppressed) {
        HiiStatementPrivate->Suppressed = TRUE;
      } else {
        if (HiiStatement->ExpressionList != NULL) {
          ExpressionResult =  EvaluateExpressionList (HiiStatement->ExpressionList, TRUE, HiiFormSet, HiiForm);
          if (ExpressionResult == ExpressGrayOut) {
            HiiStatementPrivate->GrayedOut = TRUE;
          } else if (ExpressionResult == ExpressSuppress) {
            HiiStatementPrivate->Suppressed = TRUE;
          }
        }
      }

      // Get x-UEFI-redfish string using String ID.
      Status = GetXuefiStringAndLangByStringId (FormsetPrivate, HiiStatementPrivate->Description, &String, NULL, NULL);
      if (!EFI_ERROR (Status)) {
        HiiStatementPrivate->XuefiRedfishStr = String;
        //
        // Attach to statement list.
        //
        InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
      } else {
        if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
          //
          // If there is no x-UEFI-redfish language for this statement, we don't add this statement
          // since we don't need to build menu path for attribute registry.
          //
          FreePool (HiiStatementPrivate);
        } else {
          //
          // This is not x-UEFI-redfish string and we don't cache its string for searching Redfish configure language.
          // When caller wants the string, we will read English string by calling HiiGetString().
          //
          HiiStatementPrivate->XuefiRedfishStr = NULL;
          //
          // Attach to statement list.
          //
          InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
        }
      }

      HiiStatementLink = GetNextNode (&HiiForm->StatementListHead, HiiStatementLink);
    }

    //
    // Attach to form list.
    //
    InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
    HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
  }

  return EFI_SUCCESS;

ErrorExit:

  //
  // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
  //
  if ((HiiFormSet != NULL) && (FormsetPrivate->HiiFormSet != HiiFormSet)) {
    DestroyFormSet (HiiFormSet);
  }

  //
  // Release resource when error happens.
  //
  ReleaseFormset (FormsetPrivate);

  return Status;
}

/**
  Load formset list on given HII handle.

  @param[in]  HiiHandle     HII handle to load formset list.
  @param[out] FormsetList   Pointer to formset list returned on given handle.

  @retval     EFI_STATUS

**/
EFI_STATUS
LoadFormsetList (
  IN   EFI_HII_HANDLE  *HiiHandle,
  OUT  LIST_ENTRY      *FormsetList
  )
{
  EFI_STATUS                                Status;
  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate;

  if ((HiiHandle == NULL) || (FormsetList == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
  if (FormsetPrivate != NULL) {
    return EFI_ALREADY_STARTED;
  }

  FormsetPrivate =  NewFormsetPrivate ();
  if (FormsetPrivate == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: out of resource\n", __func__));
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Load formset on the given HII handle.
  //
  Status = LoadFormset (HiiHandle, FormsetPrivate);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Formset is not loaded for edk2 redfish: %r\n", __func__, Status));
    FreePool (FormsetPrivate);
    return Status;
  }

  //
  // Attach to cache list.
  //
  InsertTailList (FormsetList, &FormsetPrivate->Link);

  DEBUG_CODE (
    if (RedfishPlatformConfigDebugProp (REDFISH_PLATFORM_CONFIG_DEBUG_DUMP_FORMSET)) {
    DumpFormsetList (FormsetList);
  }

    );

  return EFI_SUCCESS;
}

/**
  Release formset list and all the forms that belong to this formset.

  @param[in]      FormsetList   Pointer to formset list that needs to be
                                released.

  @retval         EFI_STATUS

**/
EFI_STATUS
ReleaseFormsetList (
  IN  LIST_ENTRY  *FormsetList
  )
{
  LIST_ENTRY                                *HiiFormsetLink;
  LIST_ENTRY                                *HiiFormsetNextLink;
  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;

  if (FormsetList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (IsListEmpty (FormsetList)) {
    return EFI_SUCCESS;
  }

  HiiFormsetLink = GetFirstNode (FormsetList);
  while (!IsNull (FormsetList, HiiFormsetLink)) {
    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
    HiiFormsetPrivate  = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);

    //
    // Detach from list.
    //
    RemoveEntryList (&HiiFormsetPrivate->Link);
    ReleaseFormset (HiiFormsetPrivate);
    FreePool (HiiFormsetPrivate);
    HiiFormsetLink = HiiFormsetNextLink;
  }

  return EFI_SUCCESS;
}

/**
  Get all pending list.

  @param[in]  HiiHandle   HII handle instance.
  @param[in]  PendingList Pending list to keep pending data.

  @retval REDFISH_PLATFORM_CONFIG_PENDING_LIST *   Pointer to pending list data.

**/
REDFISH_PLATFORM_CONFIG_PENDING_LIST *
GetPendingList (
  IN  EFI_HII_HANDLE  *HiiHandle,
  IN  LIST_ENTRY      *PendingList
  )
{
  LIST_ENTRY                            *PendingListLink;
  REDFISH_PLATFORM_CONFIG_PENDING_LIST  *Target;

  if ((HiiHandle == NULL) || (PendingList == NULL)) {
    return NULL;
  }

  if (IsListEmpty (PendingList)) {
    return NULL;
  }

  PendingListLink = GetFirstNode (PendingList);
  while (!IsNull (PendingList, PendingListLink)) {
    Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingListLink);

    if (Target->HiiHandle == HiiHandle) {
      return Target;
    }

    PendingListLink = GetNextNode (PendingList, PendingListLink);
  }

  return NULL;
}

/**
  When HII database is updated. Keep updated HII handle into pending list so
  we can process them later.

  @param[in]  HiiHandle   HII handle instance.
  @param[in]  PendingList Pending list to keep HII handle which is recently updated.

  @retval EFI_SUCCESS             HII handle is saved in pending list.
  @retval EFI_INVALID_PARAMETER   HiiHandle is NULL or PendingList is NULL.
  @retval EFI_OUT_OF_RESOURCES    System is out of memory.

**/
EFI_STATUS
NotifyFormsetUpdate (
  IN  EFI_HII_HANDLE  *HiiHandle,
  IN  LIST_ENTRY      *PendingList
  )
{
  REDFISH_PLATFORM_CONFIG_PENDING_LIST  *TargetPendingList;

  if ((HiiHandle == NULL) || (PendingList == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check and see if this HII handle is processed already.
  //
  TargetPendingList = GetPendingList (HiiHandle, PendingList);
  if (TargetPendingList != NULL) {
    TargetPendingList->IsDeleted = FALSE;
    DEBUG_CODE (
      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is updated\n", __func__, HiiHandle));
      );
    return EFI_SUCCESS;
  }

  TargetPendingList = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
  if (TargetPendingList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  TargetPendingList->HiiHandle = HiiHandle;
  TargetPendingList->IsDeleted = FALSE;

  InsertTailList (PendingList, &TargetPendingList->Link);

  DEBUG_CODE (
    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is created\n", __func__, HiiHandle));
    );

  return EFI_SUCCESS;
}

/**
  When HII database is updated and form-set is deleted. Keep deleted HII handle into pending list so
  we can process them later.

  @param[in]  HiiHandle   HII handle instance.
  @param[in]  PendingList Pending list to keep HII handle which is recently updated.

  @retval EFI_SUCCESS             HII handle is saved in pending list.
  @retval EFI_INVALID_PARAMETER   HiiHandle is NULL or PendingList is NULL.
  @retval EFI_OUT_OF_RESOURCES    System is out of memory.

**/
EFI_STATUS
NotifyFormsetDeleted (
  IN  EFI_HII_HANDLE  *HiiHandle,
  IN  LIST_ENTRY      *PendingList
  )
{
  REDFISH_PLATFORM_CONFIG_PENDING_LIST  *TargetPendingList;

  if ((HiiHandle == NULL) || (PendingList == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check and see if this HII handle is processed already.
  //
  TargetPendingList = GetPendingList (HiiHandle, PendingList);
  if (TargetPendingList != NULL) {
    TargetPendingList->IsDeleted = TRUE;
    DEBUG_CODE (
      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is updated and deleted\n", __func__, HiiHandle));
      );
    return EFI_SUCCESS;
  }

  TargetPendingList = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
  if (TargetPendingList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  TargetPendingList->HiiHandle = HiiHandle;
  TargetPendingList->IsDeleted = TRUE;

  InsertTailList (PendingList, &TargetPendingList->Link);

  DEBUG_CODE (
    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is deleted\n", __func__, HiiHandle));
    );

  return EFI_SUCCESS;
}

/**
  There are HII database update and we need to process them accordingly so that we
  won't use stale data. This function will parse updated HII handle again in order
  to get updated data-set.

  @param[in]  FormsetList   List to keep HII form-set.
  @param[in]  PendingList   List to keep HII handle that is updated.

  @retval EFI_SUCCESS             HII handle is saved in pending list.
  @retval EFI_INVALID_PARAMETER   FormsetList is NULL or PendingList is NULL.

**/
EFI_STATUS
ProcessPendingList (
  IN  LIST_ENTRY  *FormsetList,
  IN  LIST_ENTRY  *PendingList
  )
{
  LIST_ENTRY                                *PendingListLink;
  LIST_ENTRY                                *PendingListNextLink;
  REDFISH_PLATFORM_CONFIG_PENDING_LIST      *Target;
  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate;
  EFI_STATUS                                Status;

  if ((FormsetList == NULL) || (PendingList == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (IsListEmpty (PendingList)) {
    return EFI_SUCCESS;
  }

  PendingListLink = GetFirstNode (PendingList);
  while (!IsNull (PendingList, PendingListLink)) {
    PendingListNextLink = GetNextNode (PendingList, PendingListLink);
    Target              = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingListLink);

    if (Target->IsDeleted) {
      //
      // The HII resource on this HII handle is removed. Release the formset.
      //
      FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
      if (FormsetPrivate != NULL) {
        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset: %g is removed because driver release HII resource it already\n", __func__, &FormsetPrivate->Guid));
        RemoveEntryList (&FormsetPrivate->Link);
        ReleaseFormset (FormsetPrivate);
        FreePool (FormsetPrivate);
      } else {
        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset on HII handle 0x%x was removed already\n", __func__, Target->HiiHandle));
      }
    } else {
      //
      // The HII resource on this HII handle is updated/removed.
      //
      FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
      if (FormsetPrivate != NULL) {
        //
        // HII formset already exist, release it and query again.
        //
        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset: %g is updated. Release current formset\n", __func__, &FormsetPrivate->Guid));
        RemoveEntryList (&FormsetPrivate->Link);
        ReleaseFormset (FormsetPrivate);
        FreePool (FormsetPrivate);
      }

      Status = LoadFormsetList (Target->HiiHandle, FormsetList);
      if (EFI_ERROR (Status)) {
        if (Status == EFI_UNSUPPORTED) {
          DEBUG ((DEBUG_ERROR, "  The formset has no x-UEFI-redfish configurations.\n"));
        } else {
          DEBUG ((DEBUG_ERROR, "  load formset from HII handle: 0x%x failed: %r\n", Target->HiiHandle, Status));
        }
      }
    }

    //
    // Detach it from list first.
    //
    RemoveEntryList (&Target->Link);
    FreePool (Target);

    PendingListLink = PendingListNextLink;
  }

  return EFI_SUCCESS;
}

/**
  Release all resource in statement list.

  @param[in]  StatementList   Statement list to be released.

  @retval EFI_SUCCESS             All resource are released.
  @retval EFI_INVALID_PARAMETER   StatementList is NULL.

**/
EFI_STATUS
ReleaseStatementList (
  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST  *StatementList
  )
{
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF  *StatementRef;
  LIST_ENTRY                                     *NextLink;

  if (StatementList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (IsListEmpty (&StatementList->StatementList)) {
    return EFI_SUCCESS;
  }

  NextLink = GetFirstNode (&StatementList->StatementList);
  while (!IsNull (&StatementList->StatementList, NextLink)) {
    StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
    NextLink     = GetNextNode (&StatementList->StatementList, NextLink);

    RemoveEntryList (&StatementRef->Link);
    FreePool (StatementRef);
  }

  return EFI_SUCCESS;
}
