/** @file
  RedfishHttpDxe produces EdkIIRedfishHttpProtocol
  for EDK2 Redfish Feature driver to do HTTP operations.

  Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "RedfishHttpDxe.h"
#include "RedfishHttpData.h"
#include "RedfishHttpOperation.h"

REDFISH_HTTP_CACHE_PRIVATE  *mRedfishHttpCachePrivate = NULL;

/**
  Debug output the cache list.

  @param[in]    Msg            Debug message string.
  @param[in]    ErrorLevel     Output error level.
  @param[in]    CacheList      Target list to dump.

  @retval EFI_SUCCESS             Debug dump finished.
  @retval EFI_INVALID_PARAMETER   HttpCacheList is NULL.

**/
EFI_STATUS
DebugPrintHttpCacheList (
  IN  CONST CHAR8              *Msg,
  IN  UINTN                    ErrorLevel,
  IN  REDFISH_HTTP_CACHE_LIST  *CacheList
  )
{
  LIST_ENTRY               *List;
  REDFISH_HTTP_CACHE_DATA  *Data;
  UINTN                    Index;

  if (CacheList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IS_EMPTY_STRING (Msg)) {
    DEBUG ((ErrorLevel, "%a\n", Msg));
  }

  if (IsListEmpty (&CacheList->Head)) {
    DEBUG ((ErrorLevel, "list is empty\n"));
    return EFI_NOT_FOUND;
  }

  DEBUG ((ErrorLevel, "list count: %d capacity: %d\n", CacheList->Count, CacheList->Capacity));
  Data  = NULL;
  Index = 0;
  List  = GetFirstNode (&CacheList->Head);
  while (!IsNull (&CacheList->Head, List)) {
    Data = REDFISH_HTTP_CACHE_FROM_LIST (List);

    DEBUG ((ErrorLevel, "%d) Uri: %s Hit: %d\n", ++Index, Data->Uri, Data->HitCount));

    List = GetNextNode (&CacheList->Head, List);
  }

  return EFI_SUCCESS;
}

/**

  Check HTTP status code to see if we like to retry HTTP request or not.

  @param[in]  StatusCode      HTTP status code.

  @retval     BOOLEAN         Return true when we like to retry request.
                              Return false when we don't want to retry request.

**/
BOOLEAN
RedfishRetryRequired (
  IN EFI_HTTP_STATUS_CODE  *StatusCode
  )
{
  if (StatusCode == NULL) {
    return TRUE;
  }

  if ((*StatusCode == HTTP_STATUS_500_INTERNAL_SERVER_ERROR) ||
      (*StatusCode == HTTP_STATUS_UNSUPPORTED_STATUS))
  {
    return TRUE;
  }

  return FALSE;
}

/**

  Convert Unicode string to ASCII string. It's call responsibility to release returned buffer.

  @param[in]  UnicodeStr      Unicode string to convert.

  @retval     CHAR8 *         ASCII string returned.
  @retval     NULL            Errors occur.

**/
CHAR8 *
StringUnicodeToAscii (
  IN EFI_STRING  UnicodeStr
  )
{
  CHAR8       *AsciiStr;
  UINTN       AsciiStrSize;
  EFI_STATUS  Status;

  if (IS_EMPTY_STRING (UnicodeStr)) {
    return NULL;
  }

  AsciiStrSize = StrLen (UnicodeStr) + 1;
  AsciiStr     = AllocateZeroPool (AsciiStrSize);
  if (AsciiStr == NULL) {
    return NULL;
  }

  Status = UnicodeStrToAsciiStrS (UnicodeStr, AsciiStr, AsciiStrSize);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "UnicodeStrToAsciiStrS failed: %r\n", Status));
    FreePool (AsciiStr);
    return NULL;
  }

  return AsciiStr;
}

/**
  Return HTTP method in ASCII string. Caller does not need
  to free returned string buffer.

  @param[in]  Method         HTTP method.

  @retval CHAR8 *   Method in string.
**/
CHAR8 *
HttpMethodToString (
  IN  EFI_HTTP_METHOD  Method
  )
{
  switch (Method) {
    case HttpMethodGet:
      return HTTP_METHOD_GET;
      break;
    case HttpMethodPost:
      return HTTP_METHOD_POST;
      break;
    case HttpMethodPatch:
      return HTTP_METHOD_PATCH;
      break;
    case HttpMethodPut:
      return HTTP_METHOD_PUT;
      break;
    case HttpMethodDelete:
      return HTTP_METHOD_DELETE;
      break;
    default:
      break;
  }

  return "Unknown";
}

/**
  Report HTTP communication error via report status code.

  @param[in]  Method         HTTP method.
  @param[in]  Uri            The URI which has failure.
  @param[in]  HttpStatusCode HTTP status code.

**/
VOID
ReportHttpError (
  IN  EFI_HTTP_METHOD       Method,
  IN  EFI_STRING            Uri,
  IN  EFI_HTTP_STATUS_CODE  *HttpStatusCode  OPTIONAL
  )
{
  CHAR8  ErrorMsg[REDFISH_ERROR_MSG_MAX];

  if (IS_EMPTY_STRING (Uri)) {
    DEBUG ((DEBUG_ERROR, "%a: no URI to report error status\n", __func__));
    return;
  }

  //
  // Report failure of URI and HTTP status code.
  //
  AsciiSPrint (ErrorMsg, sizeof (ErrorMsg), REDFISH_HTTP_ERROR_REPORT, HttpMethodToString (Method), (HttpStatusCode == NULL ? HTTP_STATUS_UNSUPPORTED_STATUS : *HttpStatusCode), Uri);
  DEBUG ((DEBUG_ERROR, "%a\n", ErrorMsg));
  //
  // TODO:
  // Below PI status code is approved by PIWG and wait for specification published.
  // We will uncomment below report status code after PI status code get published.
  // REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4483
  //
  // REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
  //  EFI_ERROR_CODE | EFI_ERROR_MAJOR,
  //  EFI_COMPUTING_UNIT_MANAGEABILITY | EFI_MANAGEABILITY_EC_REDFISH_COMMUNICATION_ERROR,
  //  ErrorMsg,
  //  AsciiStrSize (ErrorMsg)
  //  );
}

/**
  This function create Redfish service. It's caller's responsibility to free returned
  Redfish service by calling FreeService ().

  @param[in]  This                       Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
  @param[in]  RedfishConfigServiceInfo   Redfish config service information.

  @retval     REDFISH_SERVICE  Redfish service is created.
  @retval     NULL             Errors occur.

**/
REDFISH_SERVICE
EFIAPI
RedfishCreateRedfishService (
  IN  EDKII_REDFISH_HTTP_PROTOCOL         *This,
  IN  REDFISH_CONFIG_SERVICE_INFORMATION  *RedfishConfigServiceInfo
  )
{
  EFI_STATUS                  Status;
  REDFISH_HTTP_CACHE_PRIVATE  *Private;
  REDFISH_SERVICE_PRIVATE     *NewService;
  CHAR8                       *AsciiLocation;
  CHAR8                       *Host;
  CHAR8                       *BasicAuthString;
  UINTN                       BasicAuthStrSize;
  CHAR8                       *EncodedAuthString;
  UINTN                       EncodedAuthStrSize;
  EDKII_REDFISH_AUTH_METHOD   AuthMethod;
  CHAR8                       *Username;
  CHAR8                       *Password;
  UINTN                       UsernameSize;
  UINTN                       PasswordSize;
  EFI_REST_EX_PROTOCOL        *RestEx;

  if ((This == NULL) || (RedfishConfigServiceInfo == NULL)) {
    return NULL;
  }

  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: service location: %s\n", __func__, RedfishConfigServiceInfo->RedfishServiceLocation));

  Private            = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
  BasicAuthString    = NULL;
  EncodedAuthString  = NULL;
  Username           = NULL;
  Password           = NULL;
  NewService         = NULL;
  AsciiLocation      = NULL;
  Host               = NULL;
  BasicAuthStrSize   = 0;
  EncodedAuthStrSize = 0;
  UsernameSize       = 0;
  PasswordSize       = 0;

  //
  // Build host and host name from service location
  //
  if (!IS_EMPTY_STRING (RedfishConfigServiceInfo->RedfishServiceLocation)) {
    AsciiLocation = StringUnicodeToAscii (RedfishConfigServiceInfo->RedfishServiceLocation);
    if (AsciiLocation == NULL) {
      goto ON_RELEASE;
    }

    Host = AllocateZeroPool (REDFISH_HOST_NAME_MAX);
    if (AsciiLocation == NULL) {
      goto ON_RELEASE;
    }

    if (RedfishConfigServiceInfo->RedfishServiceUseHttps) {
      AsciiSPrint (Host, REDFISH_HOST_NAME_MAX, "https://%a", AsciiLocation);
    } else {
      AsciiSPrint (Host, REDFISH_HOST_NAME_MAX, "http://%a", AsciiLocation);
    }

    DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Host: %a\n", __func__, Host));
  }

  //
  // Find Rest Ex protocol
  //
  if (RedfishConfigServiceInfo->RedfishServiceRestExHandle != NULL) {
    Status = gBS->HandleProtocol (
                    RedfishConfigServiceInfo->RedfishServiceRestExHandle,
                    &gEfiRestExProtocolGuid,
                    (VOID **)&RestEx
                    );
  } else {
    DEBUG ((DEBUG_ERROR, "%a: Rest Ex protocol is not available\n", __func__));
    goto ON_RELEASE;
  }

  //
  // Get credential
  //
  if (Private->CredentialProtocol == NULL) {
    //
    // No credential available on this system.
    //
    DEBUG ((DEBUG_WARN, "%a: no credential protocol available\n", __func__));
  } else {
    Status = Private->CredentialProtocol->GetAuthInfo (
                                            Private->CredentialProtocol,
                                            &AuthMethod,
                                            &Username,
                                            &Password
                                            );
    if (EFI_ERROR (Status) || IS_EMPTY_STRING (Username) || IS_EMPTY_STRING (Password)) {
      DEBUG ((DEBUG_ERROR, "%a: cannot get authentication information: %r\n", __func__, Status));
      goto ON_RELEASE;
    } else {
      DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Auth method: 0x%x username: %a password: %a\n", __func__, AuthMethod, Username, Password));

      //
      // Perform base64 encoding (RFC 7617)
      //
      UsernameSize     = AsciiStrSize (Username);
      PasswordSize     = AsciiStrSize (Password);
      BasicAuthStrSize =  UsernameSize + PasswordSize;  // one byte taken from null-terminator for ':'
      BasicAuthString  = AllocateZeroPool (BasicAuthStrSize);
      if (BasicAuthString == NULL) {
        goto ON_RELEASE;
      }

      AsciiSPrint (
        BasicAuthString,
        BasicAuthStrSize,
        "%a:%a",
        Username,
        Password
        );

      Status = Base64Encode (
                 (CONST UINT8 *)BasicAuthString,
                 BasicAuthStrSize,
                 EncodedAuthString,
                 &EncodedAuthStrSize
                 );
      if ((Status == EFI_BUFFER_TOO_SMALL) && (EncodedAuthStrSize > 0)) {
        EncodedAuthString = AllocateZeroPool (EncodedAuthStrSize);
        if (EncodedAuthString == NULL) {
          goto ON_RELEASE;
        }

        Status = Base64Encode (
                   (CONST UINT8 *)BasicAuthString,
                   BasicAuthStrSize,
                   EncodedAuthString,
                   &EncodedAuthStrSize
                   );
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_ERROR, "%a: Base64Encode failure: %r\n", __func__, Status));
        }

        DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Basic authorization: %a\n", __func__, EncodedAuthString));
      } else {
        DEBUG ((DEBUG_ERROR, "%a: Base64Encode failure: %r\n", __func__, Status));
        goto ON_RELEASE;
      }
    }
  }

  NewService = CreateRedfishService (Host, AsciiLocation, EncodedAuthString, NULL, RestEx);
  if (NewService == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: CreateRedfishService\n", __func__));
  }

ON_RELEASE:

  if (BasicAuthString != NULL) {
    ZeroMem (BasicAuthString, BasicAuthStrSize);
    FreePool (BasicAuthString);
  }

  if (EncodedAuthString != NULL) {
    ZeroMem (BasicAuthString, EncodedAuthStrSize);
    FreePool (EncodedAuthString);
  }

  if (Username != NULL) {
    ZeroMem (Username, UsernameSize);
    FreePool (Username);
  }

  if (Password != NULL) {
    ZeroMem (Password, PasswordSize);
    FreePool (Password);
  }

  if (AsciiLocation != NULL) {
    FreePool (AsciiLocation);
  }

  if (Host != NULL) {
    FreePool (Host);
  }

  return NewService;
}

/**
  This function free resources in Redfish service. RedfishService is no longer available
  after this function returns successfully.

  @param[in]  This            Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
  @param[in]  RedfishService  Pointer to Redfish service to be released.

  @retval     EFI_SUCCESS     Resource is released successfully.
  @retval     Others          Errors occur.

**/
EFI_STATUS
EFIAPI
RedfishFreeRedfishService (
  IN  EDKII_REDFISH_HTTP_PROTOCOL  *This,
  IN  REDFISH_SERVICE              RedfishService
  )
{
  REDFISH_SERVICE_PRIVATE  *Service;

  if ((This == NULL) || (RedfishService == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Service = (REDFISH_SERVICE_PRIVATE *)RedfishService;
  if (Service->Signature != REDFISH_HTTP_SERVICE_SIGNATURE) {
    DEBUG ((DEBUG_ERROR, "%a: signature check failure\n", __func__));
  }

  return ReleaseRedfishService (Service);
}

/**
  This function returns JSON value in given RedfishPayload. Returned JSON value
  is a reference to the JSON value in RedfishPayload. Any modification to returned
  JSON value will change JSON value in RedfishPayload.

  @param[in]  This            Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
  @param[in]  RedfishPayload  Pointer to Redfish payload.

  @retval     EDKII_JSON_VALUE   JSON value is returned.
  @retval     NULL               Errors occur.

**/
EDKII_JSON_VALUE
EFIAPI
RedfishJsonInRedfishPayload (
  IN  EDKII_REDFISH_HTTP_PROTOCOL  *This,
  IN  REDFISH_PAYLOAD              RedfishPayload
  )
{
  REDFISH_PAYLOAD_PRIVATE  *Payload;

  if ((This == NULL) || (RedfishPayload == NULL)) {
    return NULL;
  }

  Payload = (REDFISH_PAYLOAD_PRIVATE *)RedfishPayload;
  if (Payload->Signature != REDFISH_HTTP_PAYLOAD_SIGNATURE) {
    DEBUG ((DEBUG_ERROR, "%a: signature check failure\n", __func__));
  }

  return Payload->JsonValue;
}

/**
  Perform HTTP GET to Get redfish resource from given resource URI with
  cache mechanism supported. It's caller's responsibility to free Response
  by calling FreeResponse ().

  @param[in]  This          Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
  @param[in]  Service       Redfish service instance to perform HTTP GET.
  @param[in]  Uri           Target resource URI.
  @param[in]  Request       Additional request context. This is optional.
  @param[out] Response      HTTP response from redfish service.
  @param[in]  UseCache      If it is TRUE, this function will search for
                            cache first. If it is FALSE, this function
                            will query Redfish URI directly.

  @retval     EFI_SUCCESS     Resource is returned successfully.
  @retval     Others          Errors occur.

**/
EFI_STATUS
EFIAPI
RedfishGetResource (
  IN  EDKII_REDFISH_HTTP_PROTOCOL  *This,
  IN  REDFISH_SERVICE              Service,
  IN  EFI_STRING                   Uri,
  IN  REDFISH_REQUEST              *Request OPTIONAL,
  OUT REDFISH_RESPONSE             *Response,
  IN  BOOLEAN                      UseCache
  )
{
  EFI_STATUS                  Status;
  REDFISH_HTTP_CACHE_DATA     *CacheData;
  UINTN                       RetryCount;
  REDFISH_HTTP_CACHE_PRIVATE  *Private;

  if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri)) {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Get URI: %s cache: %a\n", __func__, Uri, (UseCache ? "true" : "false")));

  Private    = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
  CacheData  = NULL;
  RetryCount = 0;
  ZeroMem (Response, sizeof (REDFISH_RESPONSE));

  if (Private->CacheDisabled) {
    UseCache = FALSE;
    DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: cache is disabled by PCD!\n", __func__));
  }

  //
  // Search for cache list.
  //
  if (UseCache) {
    CacheData = FindHttpCacheData (&Private->CacheList.Head, Uri);
    if (CacheData != NULL) {
      DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: cache hit! %s\n", __func__, Uri));

      //
      // Copy cached response to caller's buffer.
      //
      Status               = CopyRedfishResponse (CacheData->Response, Response);
      CacheData->HitCount += 1;
      return Status;
    }
  }

  //
  // Get resource from redfish service.
  //
  do {
    RetryCount += 1;
    Status      = HttpSendReceive (
                    Service,
                    Uri,
                    HttpMethodGet,
                    Request,
                    Response
                    );
    DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %s :%r\n", __func__, Uri, Status));
    if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryGet)) {
      break;
    }

    //
    // Retry when BMC is not ready.
    //
    if ((Response->StatusCode != NULL)) {
      DEBUG_CODE (
        DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
        );

      if (!RedfishRetryRequired (Response->StatusCode)) {
        break;
      }

      //
      // Release response for next round of request.
      //
      This->FreeResponse (This, Response);
    }

    DEBUG ((DEBUG_WARN, "%a: RedfishGetByUriEx failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryGet));
    if (Private->RetrySetting.RetryWait > 0) {
      gBS->Stall (Private->RetrySetting.RetryWait);
    }
  } while (TRUE);

  if (EFI_ERROR (Status)) {
    DEBUG_CODE (
      DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
      );
    //
    // Report status code for Redfish failure
    //
    ReportHttpError (HttpMethodGet, Uri, Response->StatusCode);
    DEBUG ((DEBUG_ERROR, "%a: get %s failed (%d/%d): %r\n", __func__, Uri, RetryCount, Private->RetrySetting.MaximumRetryGet, Status));
    goto ON_RELEASE;
  }

  if (!Private->CacheDisabled) {
    //
    // Keep response in cache list
    //
    Status = AddHttpCacheData (&Private->CacheList, Uri, Response);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a: failed to cache %s: %r\n", __func__, Uri, Status));
      goto ON_RELEASE;
    }

    DEBUG_CODE (
      DebugPrintHttpCacheList (__func__, REDFISH_HTTP_CACHE_DEBUG_DUMP, &Private->CacheList);
      );
  }

ON_RELEASE:

  return Status;
}

/**
  This function free resources in Request. Request is no longer available
  after this function returns successfully.

  @param[in]  This         Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
  @param[in]  Request      HTTP request to be released.

  @retval     EFI_SUCCESS     Resource is released successfully.
  @retval     Others          Errors occur.

**/
EFI_STATUS
EFIAPI
RedfishFreeRequest (
  IN  EDKII_REDFISH_HTTP_PROTOCOL  *This,
  IN  REDFISH_REQUEST              *Request
  )
{
  if ((This == NULL) || (Request == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: entry\n", __func__));

  return ReleaseRedfishRequest (Request);
}

/**
  This function free resources in given Response.

  @param[in]  This         Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
  @param[in]  Response     HTTP response to be released.

  @retval     EFI_SUCCESS     Resource is released successfully.
  @retval     Others          Errors occur.

**/
EFI_STATUS
EFIAPI
RedfishFreeResponse (
  IN  EDKII_REDFISH_HTTP_PROTOCOL  *This,
  IN  REDFISH_RESPONSE             *Response
  )
{
  if ((This == NULL) || (Response == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: entry\n", __func__));

  return ReleaseRedfishResponse (Response);
}

/**
  This function expire the cached response of given URI.

  @param[in]  This         Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
  @param[in]  Uri          Target response of URI.

  @retval     EFI_SUCCESS     Target response is expired successfully.
  @retval     Others          Errors occur.

**/
EFI_STATUS
EFIAPI
RedfishExpireResponse (
  IN  EDKII_REDFISH_HTTP_PROTOCOL  *This,
  IN  EFI_STRING                   Uri
  )
{
  REDFISH_HTTP_CACHE_PRIVATE  *Private;
  REDFISH_HTTP_CACHE_DATA     *CacheData;

  if ((This == NULL) || IS_EMPTY_STRING (Uri)) {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: expire URI: %s\n", __func__, Uri));

  Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);

  CacheData = FindHttpCacheData (&Private->CacheList.Head, Uri);
  if (CacheData == NULL) {
    return EFI_NOT_FOUND;
  }

  return DeleteHttpCacheData (&Private->CacheList, CacheData);
}

/**
  Perform HTTP PATCH to send redfish resource to given resource URI.
  It's caller's responsibility to free Response by calling FreeResponse ().

  @param[in]  This          Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
  @param[in]  Service       Redfish service instance to perform HTTP PATCH.
  @param[in]  Uri           Target resource URI.
  @param[in]  Content       Data to patch.
  @param[in]  ContentSize   Size of the Content to be send to Redfish service.
                            This is optional. When ContentSize is 0, ContentSize
                            is the size of Content.
  @param[in]  ContentType   Type of the Content to be send to Redfish service.
                            This is optional. When ContentType is NULL, content
                            type HTTP_CONTENT_TYPE_APP_JSON will be used.
  @param[out] Response      HTTP response from redfish service.

  @retval     EFI_SUCCESS     Resource is returned successfully.
  @retval     Others          Errors occur.

**/
EFI_STATUS
EFIAPI
RedfishPatchResource (
  IN  EDKII_REDFISH_HTTP_PROTOCOL  *This,
  IN  REDFISH_SERVICE              Service,
  IN  EFI_STRING                   Uri,
  IN  CHAR8                        *Content,
  IN  UINTN                        ContentSize OPTIONAL,
  IN  CHAR8                        *ContentType OPTIONAL,
  OUT REDFISH_RESPONSE             *Response
  )
{
  EFI_STATUS                  Status;
  UINTN                       RetryCount;
  REDFISH_REQUEST             Request;
  REDFISH_HTTP_CACHE_PRIVATE  *Private;

  if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri) || IS_EMPTY_STRING (Content)) {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Patch URI: %s\n", __func__, Uri));

  Private    = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
  RetryCount = 0;
  ZeroMem (Response, sizeof (REDFISH_RESPONSE));
  ZeroMem (&Request, sizeof (REDFISH_REQUEST));

  Request.Content       = Content;
  Request.ContentLength = ContentSize;
  Request.ContentType   = ContentType;

  //
  // Patch resource to redfish service.
  //
  do {
    RetryCount += 1;
    Status      = HttpSendReceive (
                    Service,
                    Uri,
                    HttpMethodPatch,
                    &Request,
                    Response
                    );
    DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %s :%r\n", __func__, Uri, Status));
    if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryPatch)) {
      break;
    }

    //
    // Retry when BMC is not ready.
    //
    if ((Response->StatusCode != NULL)) {
      DEBUG_CODE (
        DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
        );

      if (!RedfishRetryRequired (Response->StatusCode)) {
        break;
      }

      //
      // Release response for next round of request.
      //
      This->FreeResponse (This, Response);
    }

    DEBUG ((DEBUG_WARN, "%a: RedfishPatchToUriEx failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryPatch));
    if (Private->RetrySetting.RetryWait > 0) {
      gBS->Stall (Private->RetrySetting.RetryWait);
    }
  } while (TRUE);

  //
  // Redfish resource is updated. Automatically expire the cached response
  // so application can directly get resource from Redfish service again.
  //
  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
  RedfishExpireResponse (This, Uri);

  if (EFI_ERROR (Status)) {
    DEBUG_CODE (
      DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
      );
    //
    // Report status code for Redfish failure
    //
    ReportHttpError (HttpMethodPatch, Uri, Response->StatusCode);
    DEBUG ((DEBUG_ERROR, "%a: patch %s failed (%d/%d): %r\n", __func__, Uri, RetryCount, Private->RetrySetting.MaximumRetryPatch, Status));
    goto ON_RELEASE;
  }

ON_RELEASE:

  return Status;
}

/**
  Perform HTTP PUT to send redfish resource to given resource URI.
  It's caller's responsibility to free Response by calling FreeResponse ().

  @param[in]  This          Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
  @param[in]  Service       Redfish service instance to perform HTTP PUT.
  @param[in]  Uri           Target resource URI.
  @param[in]  Content       Data to put.
  @param[in]  ContentSize   Size of the Content to be send to Redfish service.
                            This is optional. When ContentSize is 0, ContentSize
                            is the size of Content.
  @param[in]  ContentType   Type of the Content to be send to Redfish service.
                            This is optional. When ContentType is NULL, content
                            type HTTP_CONTENT_TYPE_APP_JSON will be used.
  @param[out] Response      HTTP response from redfish service.

  @retval     EFI_SUCCESS     Resource is returned successfully.
  @retval     Others          Errors occur.

**/
EFI_STATUS
EFIAPI
RedfishPutResource (
  IN  EDKII_REDFISH_HTTP_PROTOCOL  *This,
  IN  REDFISH_SERVICE              Service,
  IN  EFI_STRING                   Uri,
  IN  CHAR8                        *Content,
  IN  UINTN                        ContentSize OPTIONAL,
  IN  CHAR8                        *ContentType OPTIONAL,
  OUT REDFISH_RESPONSE             *Response
  )
{
  EFI_STATUS                  Status;
  UINTN                       RetryCount;
  REDFISH_REQUEST             Request;
  REDFISH_HTTP_CACHE_PRIVATE  *Private;

  if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri) || IS_EMPTY_STRING (Content)) {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Put URI: %s\n", __func__, Uri));

  Private    = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
  RetryCount = 0;
  ZeroMem (Response, sizeof (REDFISH_RESPONSE));
  ZeroMem (&Request, sizeof (REDFISH_REQUEST));

  Request.Content       = Content;
  Request.ContentLength = ContentSize;
  Request.ContentType   = ContentType;

  //
  // Patch resource to redfish service.
  //
  do {
    RetryCount += 1;
    Status      = HttpSendReceive (
                    Service,
                    Uri,
                    HttpMethodPut,
                    &Request,
                    Response
                    );
    DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %s :%r\n", __func__, Uri, Status));
    if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryPut)) {
      break;
    }

    //
    // Retry when BMC is not ready.
    //
    if ((Response->StatusCode != NULL)) {
      DEBUG_CODE (
        DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
        );

      if (!RedfishRetryRequired (Response->StatusCode)) {
        break;
      }

      //
      // Release response for next round of request.
      //
      This->FreeResponse (This, Response);
    }

    DEBUG ((DEBUG_WARN, "%a: RedfishPutToUri failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryPut));
    if (Private->RetrySetting.RetryWait > 0) {
      gBS->Stall (Private->RetrySetting.RetryWait);
    }
  } while (TRUE);

  //
  // Redfish resource is updated. Automatically expire the cached response
  // so application can directly get resource from Redfish service again.
  //
  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
  RedfishExpireResponse (This, Uri);

  if (EFI_ERROR (Status)) {
    DEBUG_CODE (
      DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
      );
    //
    // Report status code for Redfish failure
    //
    ReportHttpError (HttpMethodPut, Uri, Response->StatusCode);
    DEBUG ((DEBUG_ERROR, "%a: put %s failed (%d/%d): %r\n", __func__, Uri, RetryCount, Private->RetrySetting.MaximumRetryPut, Status));
    goto ON_RELEASE;
  }

ON_RELEASE:

  return Status;
}

/**
  Perform HTTP POST to send redfish resource to given resource URI.
  It's caller's responsibility to free Response by calling FreeResponse ().

  @param[in]  This          Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
  @param[in]  Service       Redfish service instance to perform HTTP POST.
  @param[in]  Uri           Target resource URI.
  @param[in]  Content       Data to post.
  @param[in]  ContentSize   Size of the Content to be send to Redfish service.
                            This is optional. When ContentSize is 0, ContentSize
                            is the size of Content.
  @param[in]  ContentType   Type of the Content to be send to Redfish service.
                            This is optional. When ContentType is NULL, content
                            type HTTP_CONTENT_TYPE_APP_JSON will be used.
  @param[out] Response      HTTP response from redfish service.

  @retval     EFI_SUCCESS     Resource is returned successfully.
  @retval     Others          Errors occur.

**/
EFI_STATUS
EFIAPI
RedfishPostResource (
  IN  EDKII_REDFISH_HTTP_PROTOCOL  *This,
  IN  REDFISH_SERVICE              Service,
  IN  EFI_STRING                   Uri,
  IN  CHAR8                        *Content,
  IN  UINTN                        ContentSize OPTIONAL,
  IN  CHAR8                        *ContentType OPTIONAL,
  OUT REDFISH_RESPONSE             *Response
  )
{
  EFI_STATUS                  Status;
  UINTN                       RetryCount;
  REDFISH_REQUEST             Request;
  REDFISH_HTTP_CACHE_PRIVATE  *Private;

  if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri) || IS_EMPTY_STRING (Content)) {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Post URI: %s\n", __func__, Uri));

  Private    = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
  RetryCount = 0;
  ZeroMem (Response, sizeof (REDFISH_RESPONSE));
  ZeroMem (&Request, sizeof (REDFISH_REQUEST));

  Request.Content       = Content;
  Request.ContentLength = ContentSize;
  Request.ContentType   = ContentType;

  //
  // Patch resource to redfish service.
  //
  do {
    RetryCount += 1;
    Status      = HttpSendReceive (
                    Service,
                    Uri,
                    HttpMethodPost,
                    &Request,
                    Response
                    );
    DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %s :%r\n", __func__, Uri, Status));
    if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryPost)) {
      break;
    }

    //
    // Retry when BMC is not ready.
    //
    if ((Response->StatusCode != NULL)) {
      DEBUG_CODE (
        DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
        );

      if (!RedfishRetryRequired (Response->StatusCode)) {
        break;
      }

      //
      // Release response for next round of request.
      //
      This->FreeResponse (This, Response);
    }

    DEBUG ((DEBUG_WARN, "%a: RedfishPostToUri failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryPost));
    if (Private->RetrySetting.RetryWait > 0) {
      gBS->Stall (Private->RetrySetting.RetryWait);
    }
  } while (TRUE);

  //
  // Redfish resource is updated. Automatically expire the cached response
  // so application can directly get resource from Redfish service again.
  //
  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
  RedfishExpireResponse (This, Uri);

  if (EFI_ERROR (Status)) {
    DEBUG_CODE (
      DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
      );
    //
    // Report status code for Redfish failure
    //
    ReportHttpError (HttpMethodPost, Uri, Response->StatusCode);
    DEBUG ((DEBUG_ERROR, "%a: post %s failed (%d/%d): %r\n", __func__, Uri, RetryCount, Private->RetrySetting.MaximumRetryPost, Status));
    goto ON_RELEASE;
  }

ON_RELEASE:

  return Status;
}

/**
  Perform HTTP DELETE to delete redfish resource on given resource URI.
  It's caller's responsibility to free Response by calling FreeResponse ().

  @param[in]  This          Pointer to EDKII_REDFISH_HTTP_PROTOCOL instance.
  @param[in]  Service       Redfish service instance to perform HTTP DELETE.
  @param[in]  Uri           Target resource URI.
  @param[in]  Content       JSON represented properties to be deleted. This is
                            optional.
  @param[in]  ContentSize   Size of the Content to be send to Redfish service.
                            This is optional. When ContentSize is 0, ContentSize
                            is the size of Content if Content is not NULL.
  @param[in]  ContentType   Type of the Content to be send to Redfish service.
                            This is optional. When Content is not NULL and
                            ContentType is NULL, content type HTTP_CONTENT_TYPE_APP_JSON
                            will be used.
  @param[out] Response      HTTP response from redfish service.

  @retval     EFI_SUCCESS     Resource is returned successfully.
  @retval     Others          Errors occur.

**/
EFI_STATUS
EFIAPI
RedfishDeleteResource (
  IN  EDKII_REDFISH_HTTP_PROTOCOL  *This,
  IN  REDFISH_SERVICE              Service,
  IN  EFI_STRING                   Uri,
  IN  CHAR8                        *Content OPTIONAL,
  IN  UINTN                        ContentSize OPTIONAL,
  IN  CHAR8                        *ContentType OPTIONAL,
  OUT REDFISH_RESPONSE             *Response
  )
{
  EFI_STATUS                  Status;
  UINTN                       RetryCount;
  REDFISH_REQUEST             Request;
  REDFISH_HTTP_CACHE_PRIVATE  *Private;

  if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri)) {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Delete URI: %s\n", __func__, Uri));

  Private    = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
  RetryCount = 0;
  ZeroMem (Response, sizeof (REDFISH_RESPONSE));
  ZeroMem (&Request, sizeof (REDFISH_REQUEST));

  Request.Content       = Content;
  Request.ContentLength = ContentSize;
  Request.ContentType   = ContentType;

  //
  // Patch resource to redfish service.
  //
  do {
    RetryCount += 1;
    Status      = HttpSendReceive (
                    Service,
                    Uri,
                    HttpMethodDelete,
                    &Request,
                    Response
                    );
    DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %s :%r\n", __func__, Uri, Status));
    if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryDelete)) {
      break;
    }

    //
    // Retry when BMC is not ready.
    //
    if ((Response->StatusCode != NULL)) {
      DEBUG_CODE (
        DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
        );

      if (!RedfishRetryRequired (Response->StatusCode)) {
        break;
      }

      //
      // Release response for next round of request.
      //
      This->FreeResponse (This, Response);
    }

    DEBUG ((DEBUG_WARN, "%a: RedfishDeleteByUri failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryDelete));
    if (Private->RetrySetting.RetryWait > 0) {
      gBS->Stall (Private->RetrySetting.RetryWait);
    }
  } while (TRUE);

  //
  // Redfish resource is updated. Automatically expire the cached response
  // so application can directly get resource from Redfish service again.
  //
  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
  RedfishExpireResponse (This, Uri);

  if (EFI_ERROR (Status)) {
    DEBUG_CODE (
      DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
      );
    //
    // Report status code for Redfish failure
    //
    ReportHttpError (HttpMethodDelete, Uri, Response->StatusCode);
    DEBUG ((DEBUG_ERROR, "%a: delete %s failed (%d/%d): %r\n", __func__, Uri, RetryCount, Private->RetrySetting.MaximumRetryDelete, Status));
    goto ON_RELEASE;
  }

ON_RELEASE:

  return Status;
}

EDKII_REDFISH_HTTP_PROTOCOL  mEdkIIRedfishHttpProtocol = {
  EDKII_REDFISH_HTTP_PROTOCOL_REVISION,
  RedfishCreateRedfishService,
  RedfishFreeRedfishService,
  RedfishJsonInRedfishPayload,
  RedfishGetResource,
  RedfishPatchResource,
  RedfishPutResource,
  RedfishPostResource,
  RedfishDeleteResource,
  RedfishFreeRequest,
  RedfishFreeResponse,
  RedfishExpireResponse
};

/**
  Unloads an image.

  @param[in]  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
RedfishHttpDriverUnload (
  IN EFI_HANDLE  ImageHandle
  )
{
  if (mRedfishHttpCachePrivate == NULL) {
    return EFI_SUCCESS;
  }

  if (!IsListEmpty (&mRedfishHttpCachePrivate->CacheList.Head)) {
    ReleaseCacheList (&mRedfishHttpCachePrivate->CacheList);
  }

  gBS->UninstallMultipleProtocolInterfaces (
         ImageHandle,
         &gEdkIIRedfishHttpProtocolGuid,
         &mRedfishHttpCachePrivate->Protocol,
         NULL
         );

  FreePool (mRedfishHttpCachePrivate);
  mRedfishHttpCachePrivate = NULL;

  return EFI_SUCCESS;
}

/**
  This is a EDKII_REDFISH_CREDENTIAL_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
CredentialProtocolInstalled (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  EFI_STATUS                  Status;
  REDFISH_HTTP_CACHE_PRIVATE  *Private;

  Private = (REDFISH_HTTP_CACHE_PRIVATE *)Context;
  if (Private->Signature != REDFISH_HTTP_DRIVER_SIGNATURE) {
    DEBUG ((DEBUG_ERROR, "%a: signature check failure\n", __func__));
    return;
  }

  //
  // Locate HII database protocol.
  //
  Status = gBS->LocateProtocol (
                  &gEdkIIRedfishCredentialProtocolGuid,
                  NULL,
                  (VOID **)&Private->CredentialProtocol
                  );
  if (EFI_ERROR (Status)) {
    return;
  }

  gBS->CloseEvent (Event);
}

/**
  Main entry for this driver.

  @param[in] ImageHandle     Image handle this driver.
  @param[in] SystemTable     Pointer to SystemTable.

  @retval EFI_SUCCESS     This function always complete successfully.

**/
EFI_STATUS
EFIAPI
RedfishHttpEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;
  VOID        *Registration;

  if (mRedfishHttpCachePrivate != NULL) {
    return EFI_ALREADY_STARTED;
  }

  mRedfishHttpCachePrivate = AllocateZeroPool (sizeof (REDFISH_HTTP_CACHE_PRIVATE));
  if (mRedfishHttpCachePrivate == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Initial cache list and protocol instance.
  //
  mRedfishHttpCachePrivate->Signature   = REDFISH_HTTP_DRIVER_SIGNATURE;
  mRedfishHttpCachePrivate->ImageHandle = ImageHandle;
  CopyMem (&mRedfishHttpCachePrivate->Protocol, &mEdkIIRedfishHttpProtocol, sizeof (EDKII_REDFISH_HTTP_PROTOCOL));
  mRedfishHttpCachePrivate->CacheList.Capacity = REDFISH_HTTP_CACHE_LIST_SIZE;
  mRedfishHttpCachePrivate->CacheList.Count    = 0x00;
  mRedfishHttpCachePrivate->CacheDisabled      = PcdGetBool (PcdHttpCacheDisabled);
  InitializeListHead (&mRedfishHttpCachePrivate->CacheList.Head);

  //
  // Get retry settings
  //
  mRedfishHttpCachePrivate->RetrySetting.MaximumRetryGet    = PcdGet16 (PcdHttpGetRetry);
  mRedfishHttpCachePrivate->RetrySetting.MaximumRetryPut    = PcdGet16 (PcdHttpPutRetry);
  mRedfishHttpCachePrivate->RetrySetting.MaximumRetryPatch  = PcdGet16 (PcdHttpPatchRetry);
  mRedfishHttpCachePrivate->RetrySetting.MaximumRetryPost   = PcdGet16 (PcdHttpPostRetry);
  mRedfishHttpCachePrivate->RetrySetting.MaximumRetryDelete = PcdGet16 (PcdHttpDeleteRetry);
  mRedfishHttpCachePrivate->RetrySetting.RetryWait          = PcdGet16 (PcdHttpRetryWaitInSecond) * 1000000U;

  //
  // Install the gEdkIIRedfishHttpProtocolGuid onto Handle.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &mRedfishHttpCachePrivate->ImageHandle,
                  &gEdkIIRedfishHttpProtocolGuid,
                  &mRedfishHttpCachePrivate->Protocol,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: cannot install Redfish http protocol: %r\n", __func__, Status));
    RedfishHttpDriverUnload (ImageHandle);
    return Status;
  }

  //
  // Install protocol notification if credential protocol is installed.
  //
  mRedfishHttpCachePrivate->NotifyEvent = EfiCreateProtocolNotifyEvent (
                                            &gEdkIIRedfishCredentialProtocolGuid,
                                            TPL_CALLBACK,
                                            CredentialProtocolInstalled,
                                            mRedfishHttpCachePrivate,
                                            &Registration
                                            );
  if (mRedfishHttpCachePrivate->NotifyEvent == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: failed to create protocol notification for gEdkIIRedfishCredentialProtocolGuid\n", __func__));
    ASSERT (FALSE);
    RedfishHttpDriverUnload (ImageHandle);
    return Status;
  }

  return EFI_SUCCESS;
}
