/** @file
  The implementation of EDKII Redfish Platform Config Protocol.

  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
  Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "RedfishPlatformConfigDxe.h"
#include "RedfishPlatformConfigImpl.h"

REDFISH_PLATFORM_CONFIG_PRIVATE  *mRedfishPlatformConfigPrivate = NULL;

/**
  Create a new stack instance with given stack size.

  @param[in]  StackSize  The size of stack.

  @retval REDFISH_STACK * Pointer to created stack.
  @retval NULL            Out of resource.

**/
REDFISH_STACK *
NewRedfishStack (
  IN UINTN  StackSize
  )
{
  REDFISH_STACK  *Buffer;

  if (StackSize == 0) {
    return NULL;
  }

  Buffer = AllocateZeroPool (sizeof (REDFISH_STACK));
  if (Buffer == NULL) {
    return NULL;
  }

  Buffer->Pool = AllocateZeroPool (sizeof (VOID *) * StackSize);
  if (Buffer->Pool == NULL) {
    FreePool (Buffer);
    return NULL;
  }

  Buffer->Size  = StackSize;
  Buffer->Index = 0;

  return Buffer;
}

/**
  Release stack buffer.

  @param[in]  Stack     Pointer to stack instance.

**/
VOID
ReleaseRedfishStack (
  IN REDFISH_STACK  *Stack
  )
{
  if (Stack == NULL) {
    return;
  }

  FreePool (Stack->Pool);
  FreePool (Stack);
}

/**
  Check and see if stack is empty or not.

  @param[in]  Stack     Pointer to stack instance.

  @retval TRUE          Stack is empty.
  @retval FALSE         Stack is not empty.

**/
BOOLEAN
IsEmptyRedfishStack (
  IN REDFISH_STACK  *Stack
  )
{
  return (Stack->Index == 0);
}

/**
  Push an item to stack.

  @param[in]  Stack     Pointer to stack instance.
  @param[in]  Data      Pointer to data.

  @retval EFI_OUT_OF_RESOURCES   Stack is full.
  @retval EFI_SUCCESS            Item is pushed successfully.

**/
EFI_STATUS
PushRedfishStack (
  IN REDFISH_STACK  *Stack,
  IN VOID           *Data
  )
{
  if (Stack->Index == Stack->Size) {
    return EFI_OUT_OF_RESOURCES;
  }

  Stack->Pool[Stack->Index] = Data;
  Stack->Index             += 1;

  return EFI_SUCCESS;
}

/**
  Pop an item from stack.

  @param[in]  Stack     Pointer to stack instance.

  @retval VOID *        Pointer to popped item.
  @retval NULL          Stack is empty.

**/
VOID *
PopRedfishStack (
  IN REDFISH_STACK  *Stack
  )
{
  if (IsEmptyRedfishStack (Stack)) {
    return NULL;
  }

  Stack->Index -= 1;
  return Stack->Pool[Stack->Index];
}

/**
  Seach forms in this HII package and find which form links to give form.

  @param[in]  FormPrivate   Pointer to form private instance.

  @retval REDFISH_PLATFORM_CONFIG_FORM_PRIVATE Pointer to target form
  @retval NULL                                 No form links to give form.

**/
REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *
FindFormLinkToThis (
  IN REDFISH_PLATFORM_CONFIG_FORM_PRIVATE  *FormPrivate
  )
{
  LIST_ENTRY                                 *HiiFormLink;
  LIST_ENTRY                                 *HiiNextFormLink;
  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE       *HiiFormPrivate;
  LIST_ENTRY                                 *HiiStatementLink;
  LIST_ENTRY                                 *HiiNextStatementLink;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *HiiStatementPrivate;
  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE   *HiiFormsetPrivate;

  if (FormPrivate == NULL) {
    return NULL;
  }

  HiiFormsetPrivate = FormPrivate->ParentFormset;

  if (IsListEmpty (&HiiFormsetPrivate->HiiFormList)) {
    return NULL;
  }

  HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
  while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
    HiiFormPrivate  = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
    HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);

    //
    // Skip myself
    //
    if (HiiFormPrivate == FormPrivate) {
      HiiFormLink = HiiNextFormLink;
      continue;
    }

    HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
    while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
      HiiStatementPrivate  = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
      HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);

      //
      // Check go-to opcode and find form ID. If form ID is the same ID as given form,
      // this go-to opcode links to given form.
      //
      if ((HiiStatementPrivate->HiiStatement->Operand == EFI_IFR_REF_OP) &&
          (HiiStatementPrivate->HiiStatement->Value.Value.ref.FormId == FormPrivate->HiiForm->FormId))
      {
        return HiiFormPrivate;
      }

      HiiStatementLink = HiiNextStatementLink;
    }

    HiiFormLink = HiiNextFormLink;
  }

  return NULL;
}

/**
  Build the menu path to given statement instance. It is caller's
  responsibility to free returned string buffer.

  @param[in]  StatementPrivate   Pointer to statement private instance.

  @retval CHAR8 *                Menu path to given statement.
  @retval NULL                   Can not find menu path.

**/
CHAR8 *
BuildMenPath (
  IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *StatementPrivate
  )
{
  REDFISH_STACK                         *FormStack;
  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE  *FormPrivate;
  UINTN                                 OldBufferSize;
  UINTN                                 NewBufferSize;
  CHAR8                                 *Buffer;
  CHAR8                                 *FormTitle;
  EFI_STATUS                            Status;

  Buffer        = NULL;
  OldBufferSize = 0;
  NewBufferSize = 0;
  FormStack     = NewRedfishStack (REDFISH_MENU_PATH_SIZE);
  if (FormStack == NULL) {
    return NULL;
  }

  //
  // Build form link stack
  //
  FormPrivate = StatementPrivate->ParentForm;
  Status      = PushRedfishStack (FormStack, (VOID *)FormPrivate);
  if (EFI_ERROR (Status)) {
    goto RELEASE;
  }

  do {
    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "F(%d) <-", FormPrivate->Id));
    FormPrivate = FindFormLinkToThis (FormPrivate);
    if (FormPrivate == NULL) {
      break;
    }

    PushRedfishStack (FormStack, (VOID *)FormPrivate);
    if (EFI_ERROR (Status)) {
      break;
    }
  } while (TRUE);

  if (IsEmptyRedfishStack (FormStack)) {
    goto RELEASE;
  }

  //
  // Initial Buffer to empty string for error case.
  //
  OldBufferSize = AsciiStrSize ("");
  Buffer        = AllocateCopyPool (OldBufferSize, "");
  if (Buffer == NULL) {
    goto RELEASE;
  }

  //
  // Build menu path in string format
  //
  FormPrivate = (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *)PopRedfishStack (FormStack);
  while (FormPrivate != NULL) {
    FormTitle = HiiGetEnglishAsciiString (FormPrivate->ParentFormset->HiiHandle, FormPrivate->Title);
    if (FormTitle != NULL) {
      NewBufferSize = AsciiStrSize (FormTitle) + OldBufferSize;
      Buffer        = ReallocatePool (OldBufferSize, NewBufferSize, Buffer);
      if (Buffer == NULL) {
        goto RELEASE;
      }

      OldBufferSize = NewBufferSize;
      AsciiStrCatS (Buffer, OldBufferSize, "/");
      AsciiStrCatS (Buffer, OldBufferSize, FormTitle);
      FreePool (FormTitle);
      DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, " %a\n", Buffer));
    }

    FormPrivate = (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *)PopRedfishStack (FormStack);
  }

RELEASE:

  ReleaseRedfishStack (FormStack);

  return Buffer;
}

/**
  Get the attribute name from config language.

  For example:  /Bios/Attributes/BiosOption1 is config language
  and attribute name is BiosOption1.

  @param[in]  ConfigLanguage     Config language string.

  @retval CHAR8 *                Attribute name string.
  @retval NULL                   Can not find attribute name.

**/
CHAR8 *
GetAttributeNameFromConfigLanguage (
  IN  CHAR8  *ConfigLanguage
  )
{
  CHAR8  *attributeName;
  CHAR8  *Pointer;
  UINTN  StrLen;
  UINTN  Index;
  UINTN  AttrStrLen;

  if (IS_EMPTY_STRING (ConfigLanguage)) {
    return NULL;
  }

  attributeName = NULL;
  Pointer       = NULL;
  AttrStrLen    = 0;
  StrLen        = AsciiStrLen (ConfigLanguage);

  if (ConfigLanguage[StrLen - 1] == '/') {
    //
    // wrong format
    //
    DEBUG ((DEBUG_ERROR, "%a: invalid format: %a\n", __func__, ConfigLanguage));
    ASSERT (FALSE);
    return NULL;
  }

  Index = StrLen;
  while (TRUE) {
    Index -= 1;

    if (ConfigLanguage[Index] == '/') {
      Pointer = &ConfigLanguage[Index + 1];
      break;
    }

    if (Index == 0) {
      break;
    }
  }

  //
  // Not found. There is no '/' in input string.
  //
  if (Pointer == NULL) {
    return NULL;
  }

  AttrStrLen    = StrLen - Index;
  attributeName = AllocateCopyPool (AttrStrLen, Pointer);

  return attributeName;
}

/**
  Convert one-of options to string array in Redfish attribute.

  @param[in]  HiiHandle          HII handle.
  @param[in]  SchemaName         Schema string.
  @param[in]  StatementPrivate   Pointer to statement instance.
  @param[out] Values             Attribute value array.

  @retval EFI_SUCCESS            Options are converted successfully.
  @retval Other                  Error occurs.

**/
EFI_STATUS
OneOfStatementToAttributeValues (
  IN  EFI_HII_HANDLE                             HiiHandle,
  IN  CHAR8                                      *SchemaName,
  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *StatementPrivate,
  OUT EDKII_REDFISH_POSSIBLE_VALUES              *Values
  )
{
  LIST_ENTRY           *Link;
  HII_QUESTION_OPTION  *Option;
  UINTN                Index;
  HII_STATEMENT        *HiiStatement;

  if ((HiiHandle == NULL) || (StatementPrivate == NULL) || (Values == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  HiiStatement = StatementPrivate->HiiStatement;
  ASSERT (HiiStatement != NULL);

  if (IsListEmpty (&HiiStatement->OptionListHead)) {
    return EFI_NOT_FOUND;
  }

  //
  // Loop through the option to get count
  //
  Values->ValueCount = 0;
  Link               = GetFirstNode (&HiiStatement->OptionListHead);
  while (!IsNull (&HiiStatement->OptionListHead, Link)) {
    Option = HII_QUESTION_OPTION_FROM_LINK (Link);

    if ((Option->SuppressExpression != NULL) &&
        (EvaluateExpressionList (Option->SuppressExpression, TRUE, StatementPrivate->ParentForm->ParentFormset->HiiFormSet, StatementPrivate->ParentForm->HiiForm) != ExpressFalse))
    {
      Link = GetNextNode (&HiiStatement->OptionListHead, Link);
      continue;
    }

    Values->ValueCount += 1;
    Link                = GetNextNode (&HiiStatement->OptionListHead, Link);
  }

  Values->ValueArray = AllocateZeroPool (sizeof (EDKII_REDFISH_ATTRIBUTE_VALUE) * Values->ValueCount);
  if (Values->ValueArray == NULL) {
    Values->ValueCount = 0;
    return EFI_OUT_OF_RESOURCES;
  }

  Index = 0;
  Link  = GetFirstNode (&HiiStatement->OptionListHead);
  while (!IsNull (&HiiStatement->OptionListHead, Link)) {
    Option = HII_QUESTION_OPTION_FROM_LINK (Link);

    if ((Option->SuppressExpression != NULL) &&
        (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse))
    {
      Link = GetNextNode (&HiiStatement->OptionListHead, Link);
      continue;
    }

    if (Option->Text != 0) {
      Values->ValueArray[Index].ValueName        = HiiGetRedfishAsciiString (HiiHandle, SchemaName, Option->Text);
      Values->ValueArray[Index].ValueDisplayName = HiiGetEnglishAsciiString (HiiHandle, Option->Text);
    }

    Index += 1;
    Link   = GetNextNode (&HiiStatement->OptionListHead, Link);
  }

  return EFI_SUCCESS;
}

/**
  Return Redfish attribute type from given HII statement operand.

  @param[in]  HiiStatement       Target HII statement.

  @retval EDKII_REDFISH_ATTRIBUTE_TYPES    Attribute type.

**/
EDKII_REDFISH_ATTRIBUTE_TYPES
HiiStatementToAttributeType (
  IN  HII_STATEMENT  *HiiStatement
  )
{
  EDKII_REDFISH_ATTRIBUTE_TYPES  type;

  if (HiiStatement == NULL) {
    return RedfishAttributeTypeUnknown;
  }

  type = RedfishAttributeTypeUnknown;
  switch (HiiStatement->Operand) {
    case EFI_IFR_ONE_OF_OP:
    case EFI_IFR_ORDERED_LIST_OP:
      type = RedfishAttributeTypeEnumeration;
      break;
    case EFI_IFR_STRING_OP:
      type = RedfishAttributeTypeString;
      break;
    case EFI_IFR_NUMERIC_OP:
      type = RedfishAttributeTypeInteger;
      break;
    case EFI_IFR_CHECKBOX_OP:
      type = RedfishAttributeTypeBoolean;
      break;
    case EFI_IFR_DATE_OP:
    case EFI_IFR_TIME_OP:
    default:
      DEBUG ((DEBUG_ERROR, "%a: unsupported operand: 0x%x\n", __func__, HiiStatement->Operand));
      break;
  }

  return type;
}

/**
  Zero extend integer/boolean to UINT64 for comparing.

  @param  Value                  HII Value to be converted.

**/
UINT64
ExtendHiiValueToU64 (
  IN HII_STATEMENT_VALUE  *Value
  )
{
  UINT64  Temp;

  Temp = 0;
  switch (Value->Type) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
      Temp = Value->Value.u8;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_16:
      Temp = Value->Value.u16;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_32:
      Temp = Value->Value.u32;
      break;

    case EFI_IFR_TYPE_BOOLEAN:
      Temp = Value->Value.b;
      break;

    case EFI_IFR_TYPE_TIME:
    case EFI_IFR_TYPE_DATE:
    default:
      break;
  }

  return Temp;
}

/**
  Set value of a data element in an Array by its Index in ordered list buffer.

  @param  Array                  The data array.
  @param  Type                   Type of the data in this array.
  @param  Index                  Zero based index for data in this array.
  @param  Value                  The value to be set.

**/
VOID
OrderedListSetArrayData (
  IN VOID    *Array,
  IN UINT8   Type,
  IN UINTN   Index,
  IN UINT64  Value
  )
{
  ASSERT (Array != NULL);

  switch (Type) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
      *(((UINT8 *)Array) + Index) = (UINT8)Value;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_16:
      *(((UINT16 *)Array) + Index) = (UINT16)Value;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_32:
      *(((UINT32 *)Array) + Index) = (UINT32)Value;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_64:
      *(((UINT64 *)Array) + Index) = (UINT64)Value;
      break;

    default:
      break;
  }
}

/**
  Return data element in an Array by its Index in ordered list array buffer.

  @param  Array                  The data array.
  @param  Type                   Type of the data in this array.
  @param  Index                  Zero based index for data in this array.

  @retval Value                  The data to be returned

**/
UINT64
OrderedListGetArrayData (
  IN VOID   *Array,
  IN UINT8  Type,
  IN UINTN  Index
  )
{
  UINT64  Data;

  ASSERT (Array != NULL);

  Data = 0;
  switch (Type) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
      Data = (UINT64)*(((UINT8 *)Array) + Index);
      break;

    case EFI_IFR_TYPE_NUM_SIZE_16:
      Data = (UINT64)*(((UINT16 *)Array) + Index);
      break;

    case EFI_IFR_TYPE_NUM_SIZE_32:
      Data = (UINT64)*(((UINT32 *)Array) + Index);
      break;

    case EFI_IFR_TYPE_NUM_SIZE_64:
      Data = (UINT64)*(((UINT64 *)Array) + Index);
      break;

    default:
      break;
  }

  return Data;
}

/**
  Find string ID of option if its value equals to given value.

  @param[in]  HiiStatement  Statement to search.
  @param[in]  Value         Target value.

  @retval EFI_SUCCESS       HII value is returned successfully.
  @retval Others            Errors occur

**/
EFI_STRING_ID
OrderedListOptionValueToStringId (
  IN  HII_STATEMENT  *HiiStatement,
  IN  UINT64         Value
  )
{
  LIST_ENTRY           *Link;
  HII_QUESTION_OPTION  *Option;
  UINT64               CurrentValue;

  if (HiiStatement == NULL) {
    return 0;
  }

  if (HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
    return 0;
  }

  if (IsListEmpty (&HiiStatement->OptionListHead)) {
    return 0;
  }

  Link = GetFirstNode (&HiiStatement->OptionListHead);
  while (!IsNull (&HiiStatement->OptionListHead, Link)) {
    Option = HII_QUESTION_OPTION_FROM_LINK (Link);

    CurrentValue = ExtendHiiValueToU64 (&Option->Value);
    if (Value == CurrentValue) {
      return Option->Text;
    }

    Link = GetNextNode (&HiiStatement->OptionListHead, Link);
  }

  return 0;
}

/**
  Compare two value in HII statement format.

  @param[in]  Value1        First value to compare.
  @param[in]  Value2        Second value to be compared.

  @retval INTN          0 is returned when two values are equal.
                        1 is returned when first value is greater than second value.
                        -1 is returned when second value is greater than first value.

**/
INTN
CompareHiiStatementValue (
  IN HII_STATEMENT_VALUE  *Value1,
  IN HII_STATEMENT_VALUE  *Value2
  )
{
  INTN    Result;
  UINT64  Data1;
  UINT64  Data2;

  if ((Value1 == NULL) || (Value2 == NULL)) {
    return -1;
  }

  switch (Value1->Type) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
      Data1 = Value1->Value.u8;
      break;
    case EFI_IFR_TYPE_NUM_SIZE_16:
      Data1 = Value1->Value.u16;
      break;
    case EFI_IFR_TYPE_NUM_SIZE_32:
      Data1 = Value1->Value.u32;
      break;
    case EFI_IFR_TYPE_NUM_SIZE_64:
      Data1 = Value1->Value.u64;
      break;
    case EFI_IFR_TYPE_BOOLEAN:
      Data1 = (Value1->Value.b ? 1 : 0);
      break;
    default:
      return -1;
  }

  switch (Value2->Type) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
      Data2 = Value2->Value.u8;
      break;
    case EFI_IFR_TYPE_NUM_SIZE_16:
      Data2 = Value2->Value.u16;
      break;
    case EFI_IFR_TYPE_NUM_SIZE_32:
      Data2 = Value2->Value.u32;
      break;
    case EFI_IFR_TYPE_NUM_SIZE_64:
      Data2 = Value2->Value.u64;
      break;
    case EFI_IFR_TYPE_BOOLEAN:
      Data2 = (Value2->Value.b ? 1 : 0);
      break;
    default:
      return -1;
  }

  Result = (Data1 == Data2 ? 0 : (Data1 > Data2 ? 1 : -1));

  return Result;
}

/**
  Convert HII value to the string in HII one-of opcode.

  @param[in]  HiiStatement  HII Statement private instance
  @param[in]  Value         HII Statement value

  @retval EFI_STRING_ID     The string ID in HII database.
                            0 is returned when something goes wrong.

**/
EFI_STRING_ID
HiiValueToOneOfOptionStringId (
  IN HII_STATEMENT        *HiiStatement,
  IN HII_STATEMENT_VALUE  *Value
  )
{
  LIST_ENTRY           *Link;
  HII_QUESTION_OPTION  *Option;

  if ((HiiStatement == NULL) || (Value == NULL)) {
    return 0;
  }

  if (HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
    return 0;
  }

  if (IsListEmpty (&HiiStatement->OptionListHead)) {
    return 0;
  }

  Link = GetFirstNode (&HiiStatement->OptionListHead);
  while (!IsNull (&HiiStatement->OptionListHead, Link)) {
    Option = HII_QUESTION_OPTION_FROM_LINK (Link);

    if (CompareHiiStatementValue (Value, &Option->Value) == 0) {
      return Option->Text;
    }

    Link = GetNextNode (&HiiStatement->OptionListHead, Link);
  }

  return 0;
}

/**
  Convert HII string to the value in HII one-of opcode.

  @param[in]  Statement     Statement private instance
  @param[in]  Schema        Schema string
  @param[in]  HiiString     Input string
  @param[out] Value         Value returned

  @retval EFI_SUCCESS       HII value is returned successfully.
  @retval Others            Errors occur

**/
EFI_STATUS
HiiStringToOneOfOptionValue (
  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *Statement,
  IN  CHAR8                                      *Schema,
  IN  EFI_STRING                                 HiiString,
  OUT HII_STATEMENT_VALUE                        *Value
  )
{
  LIST_ENTRY           *Link;
  HII_QUESTION_OPTION  *Option;
  EFI_STRING           TmpString;
  BOOLEAN              Found;

  if ((Statement == NULL) || IS_EMPTY_STRING (HiiString) || (Value == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
    return EFI_UNSUPPORTED;
  }

  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
    return EFI_NOT_FOUND;
  }

  Found = FALSE;
  Link  = GetFirstNode (&Statement->HiiStatement->OptionListHead);
  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
    Option = HII_QUESTION_OPTION_FROM_LINK (Link);

    TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
    if (TmpString != NULL) {
      if (StrCmp (TmpString, HiiString) == 0) {
        CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
        Found = TRUE;
      }

      FreePool (TmpString);
    }

    if (Found) {
      return EFI_SUCCESS;
    }

    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
  }

  return EFI_NOT_FOUND;
}

/**
  Convert HII value to numeric value in Redfish format.

  @param[in]  Value         Value to be converted.
  @param[out] RedfishValue  Value in Redfish format.

  @retval EFI_SUCCESS       Redfish value is returned successfully.
  @retval Others            Errors occur

**/
EFI_STATUS
HiiValueToRedfishNumeric (
  IN  HII_STATEMENT_VALUE  *Value,
  OUT EDKII_REDFISH_VALUE  *RedfishValue
  )
{
  if ((Value == NULL) || (RedfishValue == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  switch (Value->Type) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
      RedfishValue->Type          = RedfishValueTypeInteger;
      RedfishValue->Value.Integer = (INT64)Value->Value.u8;
      break;
    case EFI_IFR_TYPE_NUM_SIZE_16:
      RedfishValue->Type          = RedfishValueTypeInteger;
      RedfishValue->Value.Integer = (INT64)Value->Value.u16;
      break;
    case EFI_IFR_TYPE_NUM_SIZE_32:
      RedfishValue->Type          = RedfishValueTypeInteger;
      RedfishValue->Value.Integer = (INT64)Value->Value.u32;
      break;
    case EFI_IFR_TYPE_NUM_SIZE_64:
      RedfishValue->Type          = RedfishValueTypeInteger;
      RedfishValue->Value.Integer = (INT64)Value->Value.u64;
      break;
    case EFI_IFR_TYPE_BOOLEAN:
      RedfishValue->Type          = RedfishValueTypeBoolean;
      RedfishValue->Value.Boolean = Value->Value.b;
      break;
    default:
      RedfishValue->Type = RedfishValueTypeUnknown;
      break;
  }

  return EFI_SUCCESS;
}

/**
  Convert numeric value in Redfish format to HII value.

  @param[in]   RedfishValue  Value in Redfish format to be converted.
  @param[out]  Value         HII value returned.

  @retval EFI_SUCCESS       HII value is returned successfully.
  @retval Others            Errors occur

**/
EFI_STATUS
RedfishNumericToHiiValue (
  IN  EDKII_REDFISH_VALUE  *RedfishValue,
  OUT HII_STATEMENT_VALUE  *Value
  )
{
  if ((Value == NULL) || (RedfishValue == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  switch (RedfishValue->Type) {
    case RedfishValueTypeInteger:
      Value->Type      = EFI_IFR_TYPE_NUM_SIZE_64;
      Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
      break;
    case RedfishValueTypeBoolean:
      Value->Type    = EFI_IFR_TYPE_BOOLEAN;
      Value->Value.b = RedfishValue->Value.Boolean;
      break;
    default:
      Value->Type = EFI_IFR_TYPE_UNDEFINED;
      break;
  }

  return EFI_SUCCESS;
}

/**
  Dump the value in ordered list buffer.

  @param[in]   OrderedListStatement Ordered list statement.

**/
VOID
DumpOrderedListValue (
  IN  HII_STATEMENT  *OrderedListStatement
  )
{
  UINT8   *Value8;
  UINT16  *Value16;
  UINT32  *Value32;
  UINT64  *Value64;
  UINTN   Count;
  UINTN   Index;

  if ((OrderedListStatement == NULL) || (OrderedListStatement->Operand != EFI_IFR_ORDERED_LIST_OP)) {
    return;
  }

  DEBUG ((DEBUG_ERROR, "Value.Type= 0x%x\n", OrderedListStatement->Value.Type));
  DEBUG ((DEBUG_ERROR, "Value.BufferValueType= 0x%x\n", OrderedListStatement->Value.BufferValueType));
  DEBUG ((DEBUG_ERROR, "Value.BufferLen= 0x%x\n", OrderedListStatement->Value.BufferLen));
  DEBUG ((DEBUG_ERROR, "Value.Buffer= 0x%x\n", OrderedListStatement->Value.Buffer));
  DEBUG ((DEBUG_ERROR, "Value.MaxContainers= 0x%x\n", OrderedListStatement->ExtraData.OrderListData.MaxContainers));
  DEBUG ((DEBUG_ERROR, "StorageWidth= 0x%x\n", OrderedListStatement->StorageWidth));

  if (OrderedListStatement->Value.Buffer == NULL) {
    return;
  }

  Value8  = NULL;
  Value16 = NULL;
  Value32 = NULL;
  Value64 = NULL;
  Count   = 0;

  switch (OrderedListStatement->Value.BufferValueType) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
      Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
      Count  = OrderedListStatement->StorageWidth / sizeof (UINT8);
      for (Index = 0; Index < Count; Index++) {
        DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
      }

      break;
    case EFI_IFR_TYPE_NUM_SIZE_16:
      Value16 = (UINT16 *)OrderedListStatement->Value.Buffer;
      Count   = OrderedListStatement->StorageWidth / sizeof (UINT16);
      for (Index = 0; Index < Count; Index++) {
        DEBUG ((DEBUG_ERROR, "%d ", Value16[Index]));
      }

      break;
    case EFI_IFR_TYPE_NUM_SIZE_32:
      Value32 = (UINT32 *)OrderedListStatement->Value.Buffer;
      Count   = OrderedListStatement->StorageWidth / sizeof (UINT32);
      for (Index = 0; Index < Count; Index++) {
        DEBUG ((DEBUG_ERROR, "%d ", Value32[Index]));
      }

      break;
    case EFI_IFR_TYPE_NUM_SIZE_64:
      Value64 = (UINT64 *)OrderedListStatement->Value.Buffer;
      Count   = OrderedListStatement->StorageWidth / sizeof (UINT64);
      for (Index = 0; Index < Count; Index++) {
        DEBUG ((DEBUG_ERROR, "%d ", Value64[Index]));
      }

      break;
    default:
      Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
      Count  = OrderedListStatement->StorageWidth / sizeof (UINT8);
      for (Index = 0; Index < Count; Index++) {
        DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
      }

      break;
  }

  DEBUG ((DEBUG_ERROR, "\n"));
}

/**
  Convert HII value to the string in HII ordered list opcode. It's caller's
  responsibility to free returned buffer using FreePool().

  @param[in]  HiiStatement  HII Statement private instance
  @param[out] ReturnSize    The size of returned array

  @retval EFI_STRING_ID     The string ID array for options in ordered list.

**/
EFI_STRING_ID *
HiiValueToOrderedListOptionStringId (
  IN  HII_STATEMENT  *HiiStatement,
  OUT UINTN          *ReturnSize
  )
{
  LIST_ENTRY     *Link;
  UINTN          OptionCount;
  EFI_STRING_ID  *ReturnedArray;
  UINTN          Index;
  UINT64         Value;

  if ((HiiStatement == NULL) || (ReturnSize == NULL)) {
    return NULL;
  }

  *ReturnSize = 0;

  if (HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
    return NULL;
  }

  if (IsListEmpty (&HiiStatement->OptionListHead)) {
    return NULL;
  }

  DEBUG_CODE (
    DumpOrderedListValue (HiiStatement);
    );

  OptionCount = 0;
  Link        = GetFirstNode (&HiiStatement->OptionListHead);
  while (!IsNull (&HiiStatement->OptionListHead, Link)) {
    ++OptionCount;
    Link = GetNextNode (&HiiStatement->OptionListHead, Link);
  }

  *ReturnSize   = OptionCount;
  ReturnedArray = AllocatePool (sizeof (EFI_STRING_ID) * OptionCount);
  if (ReturnedArray == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: out of resource\n", __func__));
    *ReturnSize = 0;
    return NULL;
  }

  for (Index = 0; Index < OptionCount; Index++) {
    Value                = OrderedListGetArrayData (HiiStatement->Value.Buffer, HiiStatement->Value.BufferValueType, Index);
    ReturnedArray[Index] = OrderedListOptionValueToStringId (HiiStatement, Value);
  }

  return ReturnedArray;
}

/**
  Convert HII string to the value in HII ordered list opcode.

  @param[in]  Statement     Statement private instance
  @param[in]  Schema        Schema string
  @param[in]  HiiString     Input string
  @param[out] Value         Value returned

  @retval EFI_SUCCESS       HII value is returned successfully.
  @retval Others            Errors occur

**/
EFI_STATUS
HiiStringToOrderedListOptionValue (
  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *Statement,
  IN  CHAR8                                      *Schema,
  IN  EFI_STRING                                 HiiString,
  OUT UINT64                                     *Value
  )
{
  LIST_ENTRY           *Link;
  HII_QUESTION_OPTION  *Option;
  EFI_STRING           TmpString;
  BOOLEAN              Found;

  if ((Statement == NULL) || IS_EMPTY_STRING (HiiString) || (Value == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Value = 0;

  if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
    return EFI_UNSUPPORTED;
  }

  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
    return EFI_NOT_FOUND;
  }

  Found = FALSE;
  Link  = GetFirstNode (&Statement->HiiStatement->OptionListHead);
  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
    Option = HII_QUESTION_OPTION_FROM_LINK (Link);

    TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
    if (TmpString != NULL) {
      if (StrCmp (TmpString, HiiString) == 0) {
        *Value = ExtendHiiValueToU64 (&Option->Value);
        Found  = TRUE;
      }

      FreePool (TmpString);
    }

    if (Found) {
      return EFI_SUCCESS;
    }

    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
  }

  return EFI_NOT_FOUND;
}

/**
  Convert HII value to Redfish value.

  @param[in]  HiiHandle     HII handle.
  @param[in]  FullSchema    Schema string.
  @param[in]  HiiStatement  HII statement.
  @param[in]  Value         Value to be converted.
  @param[out] RedfishValue  Value in Redfish format.

  @retval EFI_SUCCESS       Redfish value is returned successfully.
  @retval Others            Errors occur

**/
EFI_STATUS
HiiValueToRedfishValue (
  IN  EFI_HII_HANDLE       HiiHandle,
  IN  CHAR8                *FullSchema,
  IN  HII_STATEMENT        *HiiStatement,
  IN  HII_STATEMENT_VALUE  *Value,
  OUT EDKII_REDFISH_VALUE  *RedfishValue
  )
{
  EFI_STATUS     Status;
  EFI_STRING_ID  StringId;
  UINTN          Index;
  UINTN          Count;
  EFI_STRING_ID  *StringIdArray;

  if ((HiiHandle == NULL) || (HiiStatement == NULL) || (Value == NULL) || (RedfishValue == NULL) || IS_EMPTY_STRING (FullSchema)) {
    return EFI_INVALID_PARAMETER;
  }

  StringIdArray = NULL;
  Count         = 0;
  Status        = EFI_SUCCESS;

  switch (HiiStatement->Operand) {
    case EFI_IFR_ONE_OF_OP:
      StringId = HiiValueToOneOfOptionStringId (HiiStatement, Value);
      if (StringId == 0) {
        ASSERT (FALSE);
        Status = EFI_DEVICE_ERROR;
        break;
      }

      RedfishValue->Value.Buffer = HiiGetRedfishAsciiString (HiiHandle, FullSchema, StringId);
      if (RedfishValue->Value.Buffer == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        break;
      }

      RedfishValue->Type = RedfishValueTypeString;
      break;
    case EFI_IFR_STRING_OP:
      if (Value->Type != EFI_IFR_TYPE_STRING) {
        ASSERT (FALSE);
        Status = EFI_DEVICE_ERROR;
        break;
      }

      RedfishValue->Type         = RedfishValueTypeString;
      RedfishValue->Value.Buffer = AllocatePool (StrLen ((CHAR16 *)Value->Buffer) + 1);
      UnicodeStrToAsciiStrS ((CHAR16 *)Value->Buffer, RedfishValue->Value.Buffer, StrLen ((CHAR16 *)Value->Buffer) + 1);
      break;
    case EFI_IFR_CHECKBOX_OP:
    case EFI_IFR_NUMERIC_OP:
      Status = HiiValueToRedfishNumeric (Value, RedfishValue);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "%a: failed to convert HII value to Redfish value: %r\n", __func__, Status));
        break;
      }

      break;
    case EFI_IFR_ACTION_OP:
      if (Value->Type != EFI_IFR_TYPE_ACTION) {
        ASSERT (FALSE);
        Status = EFI_DEVICE_ERROR;
        break;
      }

      //
      // Action has no value. Just return unknown type.
      //
      RedfishValue->Type = RedfishValueTypeUnknown;
      break;
    case EFI_IFR_ORDERED_LIST_OP:
      StringIdArray = HiiValueToOrderedListOptionStringId (HiiStatement, &Count);
      if (StringIdArray == NULL) {
        ASSERT (FALSE);
        Status = EFI_DEVICE_ERROR;
        break;
      }

      RedfishValue->Value.StringArray = AllocatePool (sizeof (CHAR8 *) * Count);
      if (RedfishValue->Value.StringArray == NULL) {
        ASSERT (FALSE);
        Status = EFI_OUT_OF_RESOURCES;
        break;
      }

      for (Index = 0; Index < Count; Index++) {
        ASSERT (StringIdArray[Index] != 0);
        RedfishValue->Value.StringArray[Index] = HiiGetRedfishAsciiString (HiiHandle, FullSchema, StringIdArray[Index]);
        ASSERT (RedfishValue->Value.StringArray[Index] != NULL);
      }

      RedfishValue->ArrayCount = Count;
      RedfishValue->Type       = RedfishValueTypeStringArray;

      FreePool (StringIdArray);
      break;
    default:
      DEBUG ((DEBUG_ERROR, "%a: catch unsupported type: 0x%x! Please contact with author if we need to support this type.\n", __func__, HiiStatement->Operand));
      ASSERT (FALSE);
      Status = EFI_UNSUPPORTED;
      break;
  }

  return Status;
}

/**
  Convert input ascii string to unicode string. It's caller's
  responsibility to free returned buffer using FreePool().

  @param[in]  AsciiString     Ascii string to be converted.

  @retval CHAR16 *            Unicode string on return.

**/
EFI_STRING
StrToUnicodeStr (
  IN  CHAR8  *AsciiString
  )
{
  UINTN       StringLen;
  EFI_STRING  Buffer;
  EFI_STATUS  Status;

  if ((AsciiString == NULL) || (AsciiString[0] == '\0')) {
    return NULL;
  }

  StringLen = AsciiStrLen (AsciiString) + 1;
  Buffer    = AllocatePool (StringLen * sizeof (CHAR16));
  if (Buffer == NULL) {
    return NULL;
  }

  Status = AsciiStrToUnicodeStrS (AsciiString, Buffer, StringLen);
  if (EFI_ERROR (Status)) {
    FreePool (Buffer);
    return NULL;
  }

  return Buffer;
}

/**
  Return the full Redfish schema string from the given Schema and Version.

  Returned schema string is: Schema + '.' + Version

  @param[in]  Schema      Schema string
  @param[in]  Version     Schema version string

  @retval CHAR8 *         Schema string. NULL when errors occur.

**/
CHAR8 *
GetFullSchemaString (
  IN CHAR8  *Schema,
  IN CHAR8  *Version
  )
{
  UINTN  Size;
  CHAR8  *FullName;

  if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) {
    return NULL;
  }

  Size = AsciiStrSize (CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema) + AsciiStrSize (Version);

  FullName = AllocatePool (Size);
  if (FullName == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: out-of-resource\n", __func__));
    return NULL;
  }

  AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX, Schema, Version);

  return FullName;
}

/**
  Common implementation to get statement private instance.

  @param[in]   RedfishPlatformConfigPrivate   Private instance.
  @param[in]   Schema                         Redfish schema string.
  @param[in]   ConfigureLang                  Configure language that refers to this statement.
  @param[out]  Statement                      Statement instance

  @retval EFI_SUCCESS       HII value is returned successfully.
  @retval Others            Errors occur

**/
EFI_STATUS
RedfishPlatformConfigGetStatementCommon (
  IN     REDFISH_PLATFORM_CONFIG_PRIVATE            *RedfishPlatformConfigPrivate,
  IN     CHAR8                                      *Schema,
  IN     EFI_STRING                                 ConfigureLang,
  OUT    REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  **Statement
  )
{
  EFI_STATUS                                 Status;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *TargetStatement;

  if ((RedfishPlatformConfigPrivate == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || (Statement == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Statement = NULL;

  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: ProcessPendingList failure: %r\n", __func__, Status));
    return Status;
  }

  TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
  if (TargetStatement == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: No match HII statement is found by the given %s in schema %a\n", __func__, ConfigureLang, Schema));
    return EFI_NOT_FOUND;
  }

  //
  // Find current HII question value.
  //
  Status = GetQuestionValue (
             TargetStatement->ParentForm->ParentFormset->HiiFormSet,
             TargetStatement->ParentForm->HiiForm,
             TargetStatement->HiiStatement,
             GetSetValueWithBuffer
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: failed to get question current value: %r\n", __func__, Status));
    return Status;
  }

  if (TargetStatement->HiiStatement->Value.Type == EFI_IFR_TYPE_UNDEFINED) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Return Value.
  //
  *Statement = TargetStatement;

  return EFI_SUCCESS;
}

/**
  Get Redfish value with the given Schema and Configure Language.

  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
  @param[in]   Schema              The Redfish schema to query.
  @param[in]   Version             The Redfish version to query.
  @param[in]   ConfigureLang       The target value which match this configure Language.
  @param[out]  Value               The returned value.

  @retval EFI_SUCCESS              Value is returned successfully.
  @retval Others                   Some error happened.

**/
EFI_STATUS
EFIAPI
RedfishPlatformConfigProtocolGetValue (
  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL  *This,
  IN     CHAR8                                   *Schema,
  IN     CHAR8                                   *Version,
  IN     EFI_STRING                              ConfigureLang,
  OUT    EDKII_REDFISH_VALUE                     *Value
  )
{
  EFI_STATUS                                 Status;
  REDFISH_PLATFORM_CONFIG_PRIVATE            *RedfishPlatformConfigPrivate;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *TargetStatement;
  CHAR8                                      *FullSchema;

  if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang) || (Value == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
  Value->Type                  = RedfishValueTypeUnknown;
  Value->ArrayCount            = 0;
  FullSchema                   = NULL;

  FullSchema = GetFullSchemaString (Schema, Version);
  if (FullSchema == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = RedfishPlatformConfigGetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &TargetStatement);
  if (EFI_ERROR (Status)) {
    goto RELEASE_RESOURCE;
  }

  if (TargetStatement->Suppressed) {
    Status = EFI_ACCESS_DENIED;
    goto RELEASE_RESOURCE;
  }

  Status = HiiValueToRedfishValue (
             TargetStatement->ParentForm->ParentFormset->HiiHandle,
             FullSchema,
             TargetStatement->HiiStatement,
             &TargetStatement->HiiStatement->Value,
             Value
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: HiiValueToRedfishValue failed: %r\n", __func__, Status));
  }

RELEASE_RESOURCE:

  if (FullSchema != NULL) {
    FreePool (FullSchema);
  }

  return Status;
}

/**
  Function to save question value into HII database.

  @param[in]   HiiFormset       HII form-set instance
  @param[in]   HiiForm          HII form instance
  @param[in]   HiiStatement     HII statement that keeps new value.
  @param[in]   Value            New value to apply.

  @retval EFI_SUCCESS       HII value is returned successfully.
  @retval Others            Errors occur

**/
EFI_STATUS
RedfishPlatformConfigSaveQuestionValue (
  IN  HII_FORMSET          *HiiFormset,
  IN  HII_FORM             *HiiForm,
  IN  HII_STATEMENT        *HiiStatement,
  IN  HII_STATEMENT_VALUE  *Value
  )
{
  EFI_STATUS  Status;

  if ((HiiFormset == NULL) || (HiiForm == NULL) || (HiiStatement == NULL) || (Value == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Status = SetQuestionValue (
             HiiFormset,
             HiiForm,
             HiiStatement,
             Value
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: failed to set question value: %r\n", __func__, Status));
    return Status;
  }

  Status = SubmitForm (HiiFormset, HiiForm);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: failed to submit form: %r\n", __func__, Status));
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Common implementation to set statement private instance.

  @param[in]   RedfishPlatformConfigPrivate   Private instance.
  @param[in]   Schema                         Redfish schema string.
  @param[in]   ConfigureLang                  Configure language that refers to this statement.
  @param[in]   StatementValue                 Statement value.

  @retval EFI_SUCCESS       HII value is returned successfully.
  @retval Others            Errors occur

**/
EFI_STATUS
RedfishPlatformConfigSetStatementCommon (
  IN     REDFISH_PLATFORM_CONFIG_PRIVATE  *RedfishPlatformConfigPrivate,
  IN     CHAR8                            *Schema,
  IN     EFI_STRING                       ConfigureLang,
  IN     HII_STATEMENT_VALUE              *StatementValue
  )
{
  EFI_STATUS                                 Status;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *TargetStatement;
  EFI_STRING                                 TempBuffer;
  UINT8                                      *StringArray;
  UINTN                                      Index;
  UINT64                                     Value;
  CHAR8                                      **CharArray;

  if ((RedfishPlatformConfigPrivate == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || (StatementValue == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  TempBuffer  = NULL;
  StringArray = NULL;

  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: ProcessPendingList failure: %r\n", __func__, Status));
    return Status;
  }

  TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
  if (TargetStatement == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: No match HII statement is found by the given %s in schema %a\n", __func__, ConfigureLang, Schema));
    return EFI_NOT_FOUND;
  }

  if (StatementValue->Type != TargetStatement->HiiStatement->Value.Type) {
    //
    // We treat one-of type as string in Redfish. But one-of statement is not
    // in string format from HII point of view. Do a patch here.
    //
    if ((TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP) && (StatementValue->Type == EFI_IFR_TYPE_STRING)) {
      TempBuffer = StrToUnicodeStr ((CHAR8 *)StatementValue->Buffer);
      if (TempBuffer == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      FreePool (StatementValue->Buffer);
      StatementValue->Buffer    = NULL;
      StatementValue->BufferLen = 0;

      Status = HiiStringToOneOfOptionValue (TargetStatement, Schema, TempBuffer, StatementValue);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "%a: failed to find option value by the given %s\n", __func__, TempBuffer));
        FreePool (TempBuffer);
        return EFI_NOT_FOUND;
      }

      FreePool (TempBuffer);
    } else if ((TargetStatement->HiiStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (StatementValue->Type == EFI_IFR_TYPE_STRING)) {
      //
      // We treat ordered list type as string in Redfish. But ordered list statement is not
      // in string format from HII point of view. Do a patch here.
      //
      StringArray = AllocateZeroPool (TargetStatement->HiiStatement->StorageWidth);
      if (StringArray == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      //
      // Arrange new option order from input string array
      //
      CharArray = (CHAR8 **)StatementValue->Buffer;
      for (Index = 0; Index < StatementValue->BufferLen; Index++) {
        TempBuffer = StrToUnicodeStr (CharArray[Index]);
        if (TempBuffer == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }

        Status = HiiStringToOrderedListOptionValue (TargetStatement, Schema, TempBuffer, &Value);
        if (EFI_ERROR (Status)) {
          ASSERT (FALSE);
          continue;
        }

        FreePool (TempBuffer);
        OrderedListSetArrayData (StringArray, TargetStatement->HiiStatement->Value.BufferValueType, Index, Value);
      }

      StatementValue->Type            = EFI_IFR_TYPE_BUFFER;
      StatementValue->Buffer          = StringArray;
      StatementValue->BufferLen       = TargetStatement->HiiStatement->StorageWidth;
      StatementValue->BufferValueType = TargetStatement->HiiStatement->Value.BufferValueType;
    } else if ((TargetStatement->HiiStatement->Operand == EFI_IFR_NUMERIC_OP) && (StatementValue->Type == EFI_IFR_TYPE_NUM_SIZE_64)) {
      //
      // Redfish only has numeric value type and it does not care about the value size.
      // Do a patch here so we have proper value size applied.
      //
      StatementValue->Type = TargetStatement->HiiStatement->Value.Type;
    } else {
      DEBUG ((DEBUG_ERROR, "%a: catch value type mismatch! input type: 0x%x but target value type: 0x%x\n", __func__, StatementValue->Type, TargetStatement->HiiStatement->Value.Type));
      ASSERT (FALSE);
    }
  }

  Status = RedfishPlatformConfigSaveQuestionValue (
             TargetStatement->ParentForm->ParentFormset->HiiFormSet,
             TargetStatement->ParentForm->HiiForm,
             TargetStatement->HiiStatement,
             StatementValue
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: failed to save question value: %r\n", __func__, Status));
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Set Redfish value with the given Schema and Configure Language.

  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
  @param[in]   Schema              The Redfish schema to query.
  @param[in]   Version             The Redfish version to query.
  @param[in]   ConfigureLang       The target value which match this configure Language.
  @param[in]   Value               The value to set.

  @retval EFI_SUCCESS              Value is returned successfully.
  @retval Others                   Some error happened.

**/
EFI_STATUS
EFIAPI
RedfishPlatformConfigProtocolSetValue (
  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL  *This,
  IN     CHAR8                                   *Schema,
  IN     CHAR8                                   *Version,
  IN     EFI_STRING                              ConfigureLang,
  IN     EDKII_REDFISH_VALUE                     Value
  )
{
  EFI_STATUS                       Status;
  REDFISH_PLATFORM_CONFIG_PRIVATE  *RedfishPlatformConfigPrivate;
  CHAR8                            *FullSchema;
  HII_STATEMENT_VALUE              NewValue;

  if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Value.Type == RedfishValueTypeUnknown) || (Value.Type >= RedfishValueTypeMax)) {
    return EFI_INVALID_PARAMETER;
  }

  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
  FullSchema                   = NULL;

  FullSchema = GetFullSchemaString (Schema, Version);
  if (FullSchema == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE));

  switch (Value.Type) {
    case RedfishValueTypeInteger:
    case RedfishValueTypeBoolean:
      Status = RedfishNumericToHiiValue (&Value, &NewValue);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "%a: failed to convert Redfish value to Hii value: %r\n", __func__, Status));
        goto RELEASE_RESOURCE;
      }

      break;
    case RedfishValueTypeString:
      NewValue.Type      = EFI_IFR_TYPE_STRING;
      NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
      NewValue.Buffer    = AllocateCopyPool (NewValue.BufferLen, Value.Value.Buffer);
      if (NewValue.Buffer == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto RELEASE_RESOURCE;
      }

      break;
    case RedfishValueTypeStringArray:
      NewValue.Type      = EFI_IFR_TYPE_STRING;
      NewValue.BufferLen = (UINT16)Value.ArrayCount;
      NewValue.Buffer    = (UINT8 *)Value.Value.StringArray;
      break;
    default:
      ASSERT (FALSE);
      break;
  }

  Status = RedfishPlatformConfigSetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: failed to set value to statement: %r\n", __func__, Status));
  }

RELEASE_RESOURCE:

  if (FullSchema != NULL) {
    FreePool (FullSchema);
  }

  return Status;
}

/**
  Get the list of Configure Language from platform configuration by the given Schema and RegexPattern.

  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
  @param[in]   Schema              The Redfish schema to query.
  @param[in]   Version             The Redfish version to query.
  @param[in]   RegexPattern        The target Configure Language pattern. This is used for regular expression matching.
  @param[out]  ConfigureLangList   The list of Configure Language.
  @param[out]  Count               The number of Configure Language in ConfigureLangList.

  @retval EFI_SUCCESS              ConfigureLangList is returned successfully.
  @retval Others                   Some error happened.

**/
EFI_STATUS
EFIAPI
RedfishPlatformConfigProtocolGetConfigureLang (
  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL  *This,
  IN     CHAR8                                   *Schema,
  IN     CHAR8                                   *Version,
  IN     EFI_STRING                              RegexPattern,
  OUT    EFI_STRING                              **ConfigureLangList,
  OUT    UINTN                                   *Count
  )
{
  REDFISH_PLATFORM_CONFIG_PRIVATE                 *RedfishPlatformConfigPrivate;
  EFI_STATUS                                      Status;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST  StatementList;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF   *StatementRef;
  LIST_ENTRY                                      *NextLink;
  EFI_STRING                                      TmpString;
  EFI_STRING                                      *TmpConfigureLangList;
  UINTN                                           Index;
  CHAR8                                           *FullSchema;

  if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || (Count == NULL) || (ConfigureLangList == NULL) || IS_EMPTY_STRING (RegexPattern)) {
    return EFI_INVALID_PARAMETER;
  }

  *Count                       = 0;
  *ConfigureLangList           = NULL;
  FullSchema                   = NULL;
  TmpConfigureLangList         = NULL;
  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);

  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: ProcessPendingList failure: %r\n", __func__, Status));
    return Status;
  }

  FullSchema = GetFullSchemaString (Schema, Version);
  if (FullSchema == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = GetStatementPrivateByConfigureLangRegex (
             RedfishPlatformConfigPrivate->RegularExpressionProtocol,
             &RedfishPlatformConfigPrivate->FormsetList,
             FullSchema,
             RegexPattern,
             &StatementList
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: GetStatementPrivateByConfigureLangRegex failure: %r\n", __func__, Status));
    goto RELEASE_RESOURCE;
  }

  if (!IsListEmpty (&StatementList.StatementList)) {
    TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) * StatementList.Count);
    if (TmpConfigureLangList == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto RELEASE_RESOURCE;
    }

    Index    = 0;
    NextLink = GetFirstNode (&StatementList.StatementList);
    while (!IsNull (&StatementList.StatementList, NextLink)) {
      StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
      NextLink     = GetNextNode (&StatementList.StatementList, NextLink);

      ASSERT (StatementRef->Statement->Description != 0);
      if (StatementRef->Statement->Description != 0) {
        TmpString = HiiGetRedfishString (StatementRef->Statement->ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef->Statement->Description);
        ASSERT (TmpString != NULL);
        if (TmpString != NULL) {
          TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString), TmpString);
          ASSERT (TmpConfigureLangList[Index] != NULL);
          FreePool (TmpString);
          ++Index;
        }
      }
    }
  }

  *Count             = StatementList.Count;
  *ConfigureLangList = TmpConfigureLangList;

RELEASE_RESOURCE:

  if (FullSchema != NULL) {
    FreePool (FullSchema);
  }

  ReleaseStatementList (&StatementList);

  return Status;
}

/**
  Get the list of supported Redfish schema from platform configuration.

  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
  @param[out]  SupportedSchema     The supported schema list which is separated by ';'.
                                   For example: "x-uefi-redfish-Memory.v1_7_1;x-uefi-redfish-Boot.v1_0_1"
                                   The SupportedSchema is allocated by the callee. It's caller's
                                   responsibility to free this buffer using FreePool().

  @retval EFI_SUCCESS              Schema is returned successfully.
  @retval Others                   Some error happened.

**/
EFI_STATUS
EFIAPI
RedfishPlatformConfigProtocolGetSupportedSchema (
  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL  *This,
  OUT    CHAR8                                   **SupportedSchema
  )
{
  REDFISH_PLATFORM_CONFIG_PRIVATE           *RedfishPlatformConfigPrivate;
  EFI_STATUS                                Status;
  LIST_ENTRY                                *HiiFormsetLink;
  LIST_ENTRY                                *HiiFormsetNextLink;
  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
  UINTN                                     Index;
  UINTN                                     StringSize;
  CHAR8                                     *StringBuffer;
  UINTN                                     StringIndex;

  if ((This == NULL) || (SupportedSchema == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *SupportedSchema = NULL;

  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);

  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: ProcessPendingList failure: %r\n", __func__, Status));
    return Status;
  }

  if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
    return EFI_NOT_FOUND;
  }

  //
  // Calculate for string buffer size.
  //
  StringSize     = 0;
  HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
  while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
    HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
    HiiFormsetPrivate  = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);

    if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
      for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
        StringSize += AsciiStrSize (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
      }
    }

    HiiFormsetLink = HiiFormsetNextLink;
  }

  if (StringSize == 0) {
    return EFI_NOT_FOUND;
  }

  StringBuffer = AllocatePool (StringSize);
  if (StringBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  StringIndex    = 0;
  HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
  while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
    HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
    HiiFormsetPrivate  = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);

    if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
      for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
        AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex), HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
        StringIndex              += AsciiStrLen (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
        StringBuffer[StringIndex] = ';';
        ++StringIndex;
      }
    }

    HiiFormsetLink = HiiFormsetNextLink;
  }

  StringBuffer[--StringIndex] = '\0';

  *SupportedSchema = StringBuffer;

  return EFI_SUCCESS;
}

/**
  Get Redfish default value with the given Schema and Configure Language.

  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
  @param[in]   Schema              The Redfish schema to query.
  @param[in]   Version             The Redfish version to query.
  @param[in]   ConfigureLang       The target value which match this configure Language.
  @param[in]   DefaultClass        The UEFI defined default class.
                                   Please refer to UEFI spec. 33.2.5.8 "defaults" for details.
  @param[out]  Value               The returned value.

  @retval EFI_SUCCESS              Value is returned successfully.
  @retval Others                   Some error happened.

**/
EFI_STATUS
EFIAPI
RedfishPlatformConfigProtocolGetDefaultValue (
  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL  *This,
  IN     CHAR8                                   *Schema,
  IN     CHAR8                                   *Version,
  IN     EFI_STRING                              ConfigureLang,
  IN     UINT16                                  DefaultClass,
  OUT    EDKII_REDFISH_VALUE                     *Value
  )
{
  EFI_STATUS                                 Status;
  REDFISH_PLATFORM_CONFIG_PRIVATE            *RedfishPlatformConfigPrivate;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *TargetStatement;
  CHAR8                                      *FullSchema;
  HII_STATEMENT_VALUE                        DefaultValue;

  if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang) || (Value == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
  ZeroMem (&DefaultValue, sizeof (HII_STATEMENT_VALUE));
  ZeroMem (Value, sizeof (EDKII_REDFISH_VALUE));

  FullSchema = NULL;
  FullSchema = GetFullSchemaString (Schema, Version);
  if (FullSchema == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = RedfishPlatformConfigGetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &TargetStatement);
  if (EFI_ERROR (Status)) {
    goto RELEASE_RESOURCE;
  }

  if (TargetStatement->Suppressed) {
    Status = EFI_ACCESS_DENIED;
    goto RELEASE_RESOURCE;
  }

  Status = GetQuestionDefault (TargetStatement->ParentForm->ParentFormset->HiiFormSet, TargetStatement->ParentForm->HiiForm, TargetStatement->HiiStatement, DefaultClass, &DefaultValue);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: GetQuestionDefault failed: %r\n", __func__, Status));
    goto RELEASE_RESOURCE;
  }

  Status = HiiValueToRedfishValue (
             TargetStatement->ParentForm->ParentFormset->HiiHandle,
             FullSchema,
             TargetStatement->HiiStatement,
             &DefaultValue,
             Value
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: HiiValueToRedfishValue failed: %r\n", __func__, Status));
  }

RELEASE_RESOURCE:

  if (FullSchema != NULL) {
    FreePool (FullSchema);
  }

  return Status;
}

/**
  Get Redfish attribute value with the given Schema and Configure Language.

  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
  @param[in]   Schema              The Redfish schema to query.
  @param[in]   Version             The Redfish version to query.
  @param[in]   ConfigureLang       The target value which match this configure Language.
  @param[out]  AttributeValue      The attribute value.

  @retval EFI_SUCCESS              Value is returned successfully.
  @retval Others                   Some error happened.

**/
EFI_STATUS
EFIAPI
RedfishPlatformConfigProtocolGetAttribute (
  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL  *This,
  IN     CHAR8                                   *Schema,
  IN     CHAR8                                   *Version,
  IN     EFI_STRING                              ConfigureLang,
  OUT    EDKII_REDFISH_ATTRIBUTE                 *AttributeValue
  )
{
  EFI_STATUS                                 Status;
  REDFISH_PLATFORM_CONFIG_PRIVATE            *RedfishPlatformConfigPrivate;
  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *TargetStatement;
  CHAR8                                      *FullSchema;
  CHAR8                                      *Buffer;

  if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang) || (AttributeValue == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
  ZeroMem (AttributeValue, sizeof (EDKII_REDFISH_ATTRIBUTE));
  FullSchema = NULL;
  FullSchema = GetFullSchemaString (Schema, Version);
  if (FullSchema == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = RedfishPlatformConfigGetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &TargetStatement);
  if (EFI_ERROR (Status)) {
    goto RELEASE_RESOURCE;
  }

  if (TargetStatement->Description != 0) {
    AttributeValue->AttributeName = HiiGetRedfishAsciiString (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema, TargetStatement->Description);
    Buffer                        = GetAttributeNameFromConfigLanguage (AttributeValue->AttributeName);
    if (Buffer != NULL) {
      FreePool (AttributeValue->AttributeName);
      AttributeValue->AttributeName = Buffer;
    }

    AttributeValue->DisplayName = HiiGetEnglishAsciiString (TargetStatement->ParentForm->ParentFormset->HiiHandle, TargetStatement->Description);
  }

  if (TargetStatement->Help != 0) {
    AttributeValue->HelpText = HiiGetEnglishAsciiString (TargetStatement->ParentForm->ParentFormset->HiiHandle, TargetStatement->Help);
  }

  AttributeValue->ReadOnly      = ((TargetStatement->Flags & EFI_IFR_FLAG_READ_ONLY) == 0 ? FALSE : TRUE);
  AttributeValue->ResetRequired = ((TargetStatement->Flags & EFI_IFR_FLAG_RESET_REQUIRED) == 0 ? FALSE : TRUE);
  AttributeValue->Type          = HiiStatementToAttributeType (TargetStatement->HiiStatement);
  AttributeValue->Suppress      = TargetStatement->Suppressed;
  AttributeValue->GrayedOut     = TargetStatement->GrayedOut;

  //
  // Build up menu path
  //
  AttributeValue->MenuPath = BuildMenPath (TargetStatement);
  if (AttributeValue->MenuPath == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: failed to build menu path for \"%a\"\n", __func__, AttributeValue->AttributeName));
  }

  //
  // Deal with maximum and minimum
  //
  if (AttributeValue->Type == RedfishAttributeTypeString) {
    AttributeValue->StrMaxSize = TargetStatement->StatementData.StrMaxSize;
    AttributeValue->StrMinSize = TargetStatement->StatementData.StrMinSize;
  } else if (AttributeValue->Type == RedfishAttributeTypeInteger) {
    AttributeValue->NumMaximum = TargetStatement->StatementData.NumMaximum;
    AttributeValue->NumMinimum = TargetStatement->StatementData.NumMinimum;
    AttributeValue->NumStep    = TargetStatement->StatementData.NumStep;
  }

  //
  // Provide value array if this is enumeration type.
  //
  if (TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP) {
    Status = OneOfStatementToAttributeValues (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema, TargetStatement, &AttributeValue->Values);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a: failed to convert one-of options to attribute values: %r\n", __func__, Status));
    }
  }

RELEASE_RESOURCE:

  if (FullSchema != NULL) {
    FreePool (FullSchema);
  }

  return Status;
}

/**
  Functions which are registered to receive notification of
  database events have this prototype. The actual event is encoded
  in NotifyType. The following table describes how PackageType,
  PackageGuid, Handle, and Package are used for each of the
  notification types.

  @param[in] PackageType  Package type of the notification.
  @param[in] PackageGuid  If PackageType is
                          EFI_HII_PACKAGE_TYPE_GUID, then this is
                          the pointer to the GUID from the Guid
                          field of EFI_HII_PACKAGE_GUID_HEADER.
                          Otherwise, it must be NULL.
  @param[in] Package      Points to the package referred to by the
                          notification Handle The handle of the package
                          list which contains the specified package.
  @param[in] Handle       The HII handle.
  @param[in] NotifyType   The type of change concerning the
                          database. See
                          EFI_HII_DATABASE_NOTIFY_TYPE.

**/
EFI_STATUS
EFIAPI
RedfishPlatformConfigFormUpdateNotify (
  IN UINT8                         PackageType,
  IN CONST EFI_GUID                *PackageGuid,
  IN CONST EFI_HII_PACKAGE_HEADER  *Package,
  IN EFI_HII_HANDLE                Handle,
  IN EFI_HII_DATABASE_NOTIFY_TYPE  NotifyType
  )
{
  EFI_STATUS  Status;

  if ((NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK) || (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK)) {
    //
    // HII formset on this handle is updated by driver during run-time. The formset needs to be reloaded.
    //
    Status = NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate->PendingList);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a: failed to notify updated formset of HII handle: 0x%x\n", __func__, Handle));
      return Status;
    }
  } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
    //
    // HII resource is removed. The formset is no longer exist.
    //
    Status = NotifyFormsetDeleted (Handle, &mRedfishPlatformConfigPrivate->PendingList);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a: failed to notify deleted formset of HII handle: 0x%x\n", __func__, Handle));
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/**
  This is a EFI_HII_STRING_PROTOCOL notification event handler.

  Install HII package notification.

  @param[in] Event    Event whose notification function is being invoked.
  @param[in] Context  Pointer to the notification function's context.

**/
VOID
EFIAPI
HiiStringProtocolInstalled (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  EFI_STATUS  Status;

  //
  // Locate HII database protocol.
  //
  Status = gBS->LocateProtocol (
                  &gEfiHiiStringProtocolGuid,
                  NULL,
                  (VOID **)&mRedfishPlatformConfigPrivate->HiiString
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: locate EFI_HII_STRING_PROTOCOL failure: %r\n", __func__, Status));
    return;
  }

  gBS->CloseEvent (Event);
  mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = NULL;
}

/**
  This is a EFI_HII_DATABASE_PROTOCOL notification event handler.

  Install HII package notification.

  @param[in] Event    Event whose notification function is being invoked.
  @param[in] Context  Pointer to the notification function's context.

**/
VOID
EFIAPI
HiiDatabaseProtocolInstalled (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  EFI_STATUS  Status;

  //
  // Locate HII database protocol.
  //
  Status = gBS->LocateProtocol (
                  &gEfiHiiDatabaseProtocolGuid,
                  NULL,
                  (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: locate EFI_HII_DATABASE_PROTOCOL failure: %r\n", __func__, Status));
    return;
  }

  //
  // Register package notification when new form package is installed.
  //
  Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
                                                         mRedfishPlatformConfigPrivate->HiiDatabase,
                                                         EFI_HII_PACKAGE_FORMS,
                                                         NULL,
                                                         RedfishPlatformConfigFormUpdateNotify,
                                                         EFI_HII_DATABASE_NOTIFY_NEW_PACK,
                                                         &mRedfishPlatformConfigPrivate->NotifyHandle
                                                         );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __func__, Status));
  }

  //
  // Register package notification when new form package is updated.
  //
  Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
                                                         mRedfishPlatformConfigPrivate->HiiDatabase,
                                                         EFI_HII_PACKAGE_FORMS,
                                                         NULL,
                                                         RedfishPlatformConfigFormUpdateNotify,
                                                         EFI_HII_DATABASE_NOTIFY_ADD_PACK,
                                                         &mRedfishPlatformConfigPrivate->NotifyHandle
                                                         );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __func__, Status));
  }

  gBS->CloseEvent (Event);
  mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = NULL;
}

/**
  This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler.

  @param[in] Event    Event whose notification function is being invoked.
  @param[in] Context  Pointer to the notification function's context.

**/
VOID
EFIAPI
RegexProtocolInstalled (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  EFI_STATUS  Status;

  //
  // Locate regular expression protocol.
  //
  Status = gBS->LocateProtocol (
                  &gEfiRegularExpressionProtocolGuid,
                  NULL,
                  (VOID **)&mRedfishPlatformConfigPrivate->RegularExpressionProtocol
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: locate EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __func__, Status));
    return;
  }

  gBS->CloseEvent (Event);
  mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
}

/**
  Unloads an image.

  @param  ImageHandle           Handle that identifies the image to be unloaded.

  @retval EFI_SUCCESS           The image has been unloaded.
  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.

**/
EFI_STATUS
EFIAPI
RedfishPlatformConfigDxeUnload (
  IN EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS  Status;

  if (mRedfishPlatformConfigPrivate != NULL) {
    Status = gBS->UninstallProtocolInterface (
                    mRedfishPlatformConfigPrivate->ImageHandle,
                    &gEdkIIRedfishPlatformConfigProtocolGuid,
                    (VOID *)&mRedfishPlatformConfigPrivate->Protocol
                    );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a: can not uninstall gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __func__, Status));
      ASSERT (FALSE);
    }

    //
    // Close events
    //
    if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
      gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent);
    }

    if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent != NULL) {
      gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent);
    }

    if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL) {
      gBS->CloseEvent (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent);
    }

    //
    // Unregister package notification.
    //
    if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
      mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify (
                                                    mRedfishPlatformConfigPrivate->HiiDatabase,
                                                    mRedfishPlatformConfigPrivate->NotifyHandle
                                                    );
    }

    ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
    FreePool (mRedfishPlatformConfigPrivate);
    mRedfishPlatformConfigPrivate = NULL;
  }

  return EFI_SUCCESS;
}

/**
  This is the declaration of an EFI image entry point. This entry point is
  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
  both device drivers and bus drivers.

  @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
RedfishPlatformConfigDxeEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  mRedfishPlatformConfigPrivate = (REDFISH_PLATFORM_CONFIG_PRIVATE *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
  if (mRedfishPlatformConfigPrivate == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: can not allocate pool for REDFISH_PLATFORM_CONFIG_PRIVATE\n", __func__));
    ASSERT (FALSE);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Protocol initialization
  //
  mRedfishPlatformConfigPrivate->ImageHandle                 = ImageHandle;
  mRedfishPlatformConfigPrivate->Protocol.Revision           = REDFISH_PLATFORM_CONFIG_VERSION;
  mRedfishPlatformConfigPrivate->Protocol.GetValue           = RedfishPlatformConfigProtocolGetValue;
  mRedfishPlatformConfigPrivate->Protocol.SetValue           = RedfishPlatformConfigProtocolSetValue;
  mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang   = RedfishPlatformConfigProtocolGetConfigureLang;
  mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema = RedfishPlatformConfigProtocolGetSupportedSchema;
  mRedfishPlatformConfigPrivate->Protocol.GetAttribute       = RedfishPlatformConfigProtocolGetAttribute;
  mRedfishPlatformConfigPrivate->Protocol.GetDefaultValue    = RedfishPlatformConfigProtocolGetDefaultValue;

  InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
  InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);

  Status = gBS->InstallProtocolInterface (
                  &ImageHandle,
                  &gEdkIIRedfishPlatformConfigProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  (VOID *)&mRedfishPlatformConfigPrivate->Protocol
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: can not install gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __func__, Status));
    ASSERT (FALSE);
  }

  //
  // Install protocol notification if HII database protocol is installed.
  //
  mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
                                                               &gEfiHiiDatabaseProtocolGuid,
                                                               TPL_CALLBACK,
                                                               HiiDatabaseProtocolInstalled,
                                                               NULL,
                                                               &mRedfishPlatformConfigPrivate->HiiDbNotify.Registration
                                                               );
  if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: failed to create protocol notification for gEfiHiiDatabaseProtocolGuid\n", __func__));
    ASSERT (FALSE);
  }

  //
  // Install protocol notification if HII string protocol is installed.
  //
  mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
                                                                   &gEfiHiiStringProtocolGuid,
                                                                   TPL_CALLBACK,
                                                                   HiiStringProtocolInstalled,
                                                                   NULL,
                                                                   &mRedfishPlatformConfigPrivate->HiiStringNotify.Registration
                                                                   );
  if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: failed to create protocol notification for gEfiHiiStringProtocolGuid\n", __func__));
    ASSERT (FALSE);
  }

  //
  // Install protocol notification if regular expression protocol is installed.
  //
  mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
                                                               &gEfiRegularExpressionProtocolGuid,
                                                               TPL_CALLBACK,
                                                               RegexProtocolInstalled,
                                                               NULL,
                                                               &mRedfishPlatformConfigPrivate->RegexNotify.Registration
                                                               );
  if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: failed to create protocol notification for gEfiRegularExpressionProtocolGuid\n", __func__));
    ASSERT (FALSE);
  }

  return EFI_SUCCESS;
}
