/** @file
  RedfishHttpData handles internal data to support Redfish HTTP protocol.

  Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "RedfishHttpData.h"
#include "RedfishHttpOperation.h"

/**
  This function update session token in Redfish Service.

  @param[in]  Service         Pointer to service instance.
  @param[in]  Token           Session token.

  @retval     EFI_SUCCESS     Session token is updated.
  @retval     Others          Error occurs.

**/
EFI_STATUS
UpdateSessionToken (
  IN REDFISH_SERVICE_PRIVATE  *Service,
  IN CHAR8                    *Token
  )
{
  if ((Service == NULL) || IS_EMPTY_STRING (Token)) {
    return EFI_INVALID_PARAMETER;
  }

  if (Service->SessionToken != NULL) {
    FreePool (Service->SessionToken);
  }

  Service->SessionToken = ASCII_STR_DUPLICATE (Token);
  if (Service->SessionToken == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  This function release Redfish Service.

  @param[in]  Service         Pointer to service instance.

  @retval     EFI_SUCCESS     Service is released.
  @retval     Others          Error occurs.

**/
EFI_STATUS
ReleaseRedfishService (
  IN REDFISH_SERVICE_PRIVATE  *Service
  )
{
  if (Service == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Service->Host != NULL) {
    FreePool (Service->Host);
  }

  if (Service->HostName != NULL) {
    FreePool (Service->HostName);
  }

  if (Service->BasicAuth != NULL) {
    ZeroMem (Service->BasicAuth, AsciiStrSize (Service->BasicAuth));
    FreePool (Service->BasicAuth);
  }

  if (Service->SessionToken != NULL) {
    ZeroMem (Service->SessionToken, AsciiStrSize (Service->SessionToken));
    FreePool (Service->SessionToken);
  }

  FreePool (Service);

  return EFI_SUCCESS;
}

/**
  This function create new service. Host and HostName are copied to
  newly created service instance.

  @param[in]  Host            Host string.
  @param[in]  HostName        Hostname string.
  @param[in]  BasicAuth       Basic Authorization string.
  @param[in]  SessionToken    Session token string.
  @param[in]  RestEx          Rest EX protocol instance.

  @retval     REDFISH_PAYLOAD_PRIVATE  Newly created service.
  @retval     NULL             Error occurs.

**/
REDFISH_SERVICE_PRIVATE *
CreateRedfishService (
  IN CHAR8                 *Host,
  IN CHAR8                 *HostName,
  IN CHAR8                 *BasicAuth OPTIONAL,
  IN CHAR8                 *SessionToken OPTIONAL,
  IN EFI_REST_EX_PROTOCOL  *RestEx
  )
{
  REDFISH_SERVICE_PRIVATE  *NewService;
  UINTN                    AuthStrSize;

  if (IS_EMPTY_STRING (Host) || IS_EMPTY_STRING (HostName) || (RestEx == NULL)) {
    return NULL;
  }

  NewService = AllocateZeroPool (sizeof (REDFISH_SERVICE_PRIVATE));
  if (NewService == NULL) {
    return NULL;
  }

  NewService->Signature = REDFISH_HTTP_SERVICE_SIGNATURE;
  NewService->Host      = ASCII_STR_DUPLICATE (Host);
  if (NewService->Host == NULL) {
    goto ON_ERROR;
  }

  NewService->HostName = ASCII_STR_DUPLICATE (HostName);
  if (NewService->HostName == NULL) {
    goto ON_ERROR;
  }

  if (!IS_EMPTY_STRING (BasicAuth)) {
    AuthStrSize           = AsciiStrSize (BasicAuth) + AsciiStrLen (REDFISH_HTTP_BASIC_AUTH_STR);
    NewService->BasicAuth = AllocateZeroPool (AuthStrSize);
    if (NewService->BasicAuth == NULL) {
      goto ON_ERROR;
    }

    AsciiSPrint (NewService->BasicAuth, AuthStrSize, "%a%a", REDFISH_HTTP_BASIC_AUTH_STR, BasicAuth);
  }

  if (!IS_EMPTY_STRING (SessionToken)) {
    NewService->SessionToken = ASCII_STR_DUPLICATE (SessionToken);
    if (NewService->SessionToken == NULL) {
      goto ON_ERROR;
    }
  }

  NewService->RestEx = RestEx;

  return NewService;

ON_ERROR:

  ReleaseRedfishService (NewService);

  return NULL;
}

/**
  This function release Redfish Payload.

  @param[in]  Payload         Pointer to payload instance.

  @retval     EFI_SUCCESS     Payload is released.
  @retval     Others          Error occurs.

**/
EFI_STATUS
ReleaseRedfishPayload (
  IN REDFISH_PAYLOAD_PRIVATE  *Payload
  )
{
  if (Payload == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Payload->Service != NULL) {
    ReleaseRedfishService (Payload->Service);
  }

  if (Payload->JsonValue != NULL) {
    JsonValueFree (Payload->JsonValue);
  }

  FreePool (Payload);

  return EFI_SUCCESS;
}

/**
  This function create new payload. Server and JsonObj are
  copied to newly created payload.

  @param[in]  Service          Pointer to Service instance.
  @param[in]  JsonValue        Pointer to JSON value.

  @retval     REDFISH_PAYLOAD_PRIVATE  Newly created payload.
  @retval     NULL                     Error occurs.

**/
REDFISH_PAYLOAD_PRIVATE *
CreateRedfishPayload (
  IN REDFISH_SERVICE_PRIVATE  *Service,
  IN EDKII_JSON_VALUE         JsonValue
  )
{
  REDFISH_PAYLOAD_PRIVATE  *NewPayload;

  if ((Service == NULL) || (JsonValue == NULL)) {
    return NULL;
  }

  NewPayload = AllocateZeroPool (sizeof (REDFISH_PAYLOAD_PRIVATE));
  if (NewPayload == NULL) {
    return NULL;
  }

  NewPayload->Signature = REDFISH_HTTP_PAYLOAD_SIGNATURE;
  NewPayload->Service   = CreateRedfishService (Service->Host, Service->HostName, Service->BasicAuth, Service->SessionToken, Service->RestEx);
  if (NewPayload->Service == NULL) {
    goto ON_ERROR;
  }

  NewPayload->JsonValue = JsonValueClone (JsonValue);
  if (NewPayload->JsonValue == NULL) {
    goto ON_ERROR;
  }

  return NewPayload;

ON_ERROR:

  ReleaseRedfishPayload (NewPayload);

  return NULL;
}

/**
  This function copy the data in SrcResponse to DstResponse.

  @param[in]  SrcResponse      Source Response to copy.
  @param[out] DstResponse      Destination Response.

  @retval     EFI_SUCCESS      Response is copied successfully.
  @retval     Others           Error occurs.

**/
EFI_STATUS
CopyRedfishResponse (
  IN  REDFISH_RESPONSE  *SrcResponse,
  OUT REDFISH_RESPONSE  *DstResponse
  )
{
  REDFISH_PAYLOAD_PRIVATE  *Payload;
  UINTN                    Index;

  if ((SrcResponse == NULL) || (DstResponse == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (SrcResponse == DstResponse) {
    return EFI_SUCCESS;
  }

  //
  // Status code
  //
  if (SrcResponse->StatusCode != NULL) {
    DstResponse->StatusCode = AllocateCopyPool (sizeof (EFI_HTTP_STATUS_CODE), SrcResponse->StatusCode);
    if (DstResponse->StatusCode == NULL) {
      goto ON_ERROR;
    }
  }

  //
  // Header
  //
  if ((SrcResponse->HeaderCount > 0) && (SrcResponse->Headers != NULL)) {
    DstResponse->HeaderCount = 0;
    DstResponse->Headers     = AllocateZeroPool (sizeof (EFI_HTTP_HEADER) * SrcResponse->HeaderCount);
    if (DstResponse->Headers == NULL) {
      goto ON_ERROR;
    }

    DstResponse->HeaderCount = SrcResponse->HeaderCount;

    for (Index = 0; Index < SrcResponse->HeaderCount; Index++) {
      DstResponse->Headers[Index].FieldName = ASCII_STR_DUPLICATE (SrcResponse->Headers[Index].FieldName);
      if (DstResponse->Headers[Index].FieldName == NULL) {
        goto ON_ERROR;
      }

      DstResponse->Headers[Index].FieldValue = ASCII_STR_DUPLICATE (SrcResponse->Headers[Index].FieldValue);
      if (DstResponse->Headers[Index].FieldValue == NULL) {
        goto ON_ERROR;
      }
    }
  }

  //
  // Payload
  //
  if (SrcResponse->Payload != NULL) {
    Payload = (REDFISH_PAYLOAD_PRIVATE *)SrcResponse->Payload;
    if (Payload->Signature != REDFISH_HTTP_PAYLOAD_SIGNATURE) {
      DEBUG ((DEBUG_ERROR, "%a: signature check failure\n", __func__));
      goto ON_ERROR;
    }

    DstResponse->Payload = CreateRedfishPayload (Payload->Service, Payload->JsonValue);
    if (DstResponse->Payload  == NULL) {
      goto ON_ERROR;
    }
  }

  return EFI_SUCCESS;

ON_ERROR:

  ReleaseRedfishResponse (DstResponse);

  return EFI_OUT_OF_RESOURCES;
}

/**
  This function clone input response and return to caller

  @param[in]  Response      Response to clone.

  @retval     REDFISH_RESPONSE *  Response is cloned.
  @retval     NULL                Errors occur.

**/
REDFISH_RESPONSE *
CloneRedfishResponse (
  IN REDFISH_RESPONSE  *Response
  )
{
  EFI_STATUS        Status;
  REDFISH_RESPONSE  *NewResponse;

  if (Response == NULL) {
    return NULL;
  }

  NewResponse = AllocateZeroPool (sizeof (REDFISH_RESPONSE));
  if (NewResponse == NULL) {
    return NULL;
  }

  Status = CopyRedfishResponse (Response, NewResponse);
  if (EFI_ERROR (Status)) {
    FreePool (NewResponse);
    return NULL;
  }

  return NewResponse;
}

/**
  Release REDFISH_HTTP_CACHE_DATA resource

  @param[in]    Data    Pointer to REDFISH_HTTP_CACHE_DATA instance

  @retval EFI_SUCCESS             REDFISH_HTTP_CACHE_DATA is released successfully.
  @retval EFI_INVALID_PARAMETER   Data is NULL

**/
EFI_STATUS
ReleaseHttpCacheData (
  IN REDFISH_HTTP_CACHE_DATA  *Data
  )
{
  if (Data == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Data->Uri != NULL) {
    FreePool (Data->Uri);
  }

  if (Data->Response != NULL) {
    ReleaseRedfishResponse (Data->Response);
    FreePool (Data->Response);
  }

  FreePool (Data);

  return EFI_SUCCESS;
}

/**
  Create new cache data.

  @param[in]    Uri       The URI string matching to this cache data.
  @param[in]    Response  HTTP response.

  @retval REDFISH_HTTP_CACHE_DATA *   Pointer to newly created cache data.
  @retval NULL                        No memory available.

**/
REDFISH_HTTP_CACHE_DATA *
NewHttpCacheData (
  IN  EFI_STRING        Uri,
  IN  REDFISH_RESPONSE  *Response
  )
{
  REDFISH_HTTP_CACHE_DATA  *NewData;
  UINTN                    Size;

  if (IS_EMPTY_STRING (Uri) || (Response == NULL)) {
    return NULL;
  }

  NewData = AllocateZeroPool (sizeof (REDFISH_HTTP_CACHE_DATA));
  if (NewData == NULL) {
    return NULL;
  }

  NewData->Signature = REDFISH_HTTP_CACHE_SIGNATURE;
  Size               = StrSize (Uri);
  NewData->Uri       = AllocateCopyPool (Size, Uri);
  if (NewData->Uri == NULL) {
    goto ON_ERROR;
  }

  NewData->Response = Response;
  NewData->HitCount = 1;

  return NewData;

ON_ERROR:

  if (NewData != NULL) {
    ReleaseHttpCacheData (NewData);
  }

  return NULL;
}

/**
  Search on given ListHeader for given URI string.

  @param[in]    ListHeader  Target list to search.
  @param[in]    Uri         Target URI to search.

  @retval REDFISH_HTTP_CACHE_DATA   Target cache data is found.
  @retval NULL                      No cache data with given URI is found.

**/
REDFISH_HTTP_CACHE_DATA *
FindHttpCacheData (
  IN  LIST_ENTRY  *ListHeader,
  IN  EFI_STRING  Uri
  )
{
  LIST_ENTRY               *List;
  REDFISH_HTTP_CACHE_DATA  *Data;

  if (IS_EMPTY_STRING (Uri)) {
    return NULL;
  }

  if (IsListEmpty (ListHeader)) {
    return NULL;
  }

  Data = NULL;
  List = GetFirstNode (ListHeader);
  while (!IsNull (ListHeader, List)) {
    Data = REDFISH_HTTP_CACHE_FROM_LIST (List);

    if (StrCmp (Data->Uri, Uri) == 0) {
      return Data;
    }

    List = GetNextNode (ListHeader, List);
  }

  return NULL;
}

/**
  Search on given ListHeader and return cache data with minimum hit count.

  @param[in]    ListHeader  Target list to search.

  @retval REDFISH_HTTP_CACHE_DATA   Target cache data is returned.
  @retval NULL                      No cache data is found.

**/
REDFISH_HTTP_CACHE_DATA *
FindUnusedHttpCacheData (
  IN  LIST_ENTRY  *ListHeader
  )
{
  LIST_ENTRY               *List;
  REDFISH_HTTP_CACHE_DATA  *Data;
  REDFISH_HTTP_CACHE_DATA  *UnusedData;
  UINTN                    HitCount;

  if (IsListEmpty (ListHeader)) {
    return NULL;
  }

  Data       = NULL;
  UnusedData = NULL;
  HitCount   = 0;

  List       = GetFirstNode (ListHeader);
  Data       = REDFISH_HTTP_CACHE_FROM_LIST (List);
  UnusedData = Data;
  HitCount   = Data->HitCount;
  List       = GetNextNode (ListHeader, List);

  while (!IsNull (ListHeader, List)) {
    Data = REDFISH_HTTP_CACHE_FROM_LIST (List);

    if (Data->HitCount < HitCount) {
      HitCount   = Data->HitCount;
      UnusedData = Data;
    }

    List = GetNextNode (ListHeader, List);
  }

  return UnusedData;
}

/**
  Delete a cache data by given cache instance.

  @param[in]    List    Target cache list to be removed.
  @param[in]    Data    Pointer to the instance to be deleted.

  @retval EFI_SUCCESS   Cache data is removed.
  @retval Others        Fail to remove cache data.

**/
EFI_STATUS
DeleteHttpCacheData (
  IN  REDFISH_HTTP_CACHE_LIST  *List,
  IN  REDFISH_HTTP_CACHE_DATA  *Data
  )
{
  if ((List == NULL) || (Data == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: delete: %s\n", __func__, Data->Uri));

  RemoveEntryList (&Data->List);
  --List->Count;

  return ReleaseHttpCacheData (Data);
}

/**
  Add new cache by given URI and HTTP response to specify List.

  @param[in]    List      Target cache list to add.
  @param[in]    Uri       The URI string matching to this cache data.
  @param[in]    Response  HTTP response.

  @retval EFI_SUCCESS   Cache data is added.
  @retval Others        Fail to add cache data.

**/
EFI_STATUS
AddHttpCacheData (
  IN  REDFISH_HTTP_CACHE_LIST  *List,
  IN  EFI_STRING               Uri,
  IN  REDFISH_RESPONSE         *Response
  )
{
  REDFISH_HTTP_CACHE_DATA  *NewData;
  REDFISH_HTTP_CACHE_DATA  *OldData;
  REDFISH_HTTP_CACHE_DATA  *UnusedData;
  REDFISH_RESPONSE         *NewResponse;

  if ((List == NULL) || IS_EMPTY_STRING (Uri) || (Response == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // If same cache data exist, replace it with latest one.
  //
  OldData = FindHttpCacheData (&List->Head, Uri);
  if (OldData != NULL) {
    DeleteHttpCacheData (List, OldData);
  }

  //
  // Check capacity
  //
  if (List->Count >= List->Capacity) {
    DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: list is full and retire unused cache\n", __func__));
    UnusedData = FindUnusedHttpCacheData (&List->Head);
    if (UnusedData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    DeleteHttpCacheData (List, UnusedData);
  }

  //
  // Clone a local copy
  //
  NewResponse = CloneRedfishResponse (Response);
  if (NewResponse == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  NewData = NewHttpCacheData (Uri, NewResponse);
  if (NewData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  InsertTailList (&List->Head, &NewData->List);
  ++List->Count;

  DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: cache(%d/%d) %s\n", __func__, List->Count, List->Capacity, NewData->Uri));

  return EFI_SUCCESS;
}

/**
  Release all cache from list.

  @param[in]    CacheList    The list to be released.

  @retval EFI_SUCCESS             All cache data are released.
  @retval EFI_INVALID_PARAMETER   CacheList is NULL.

**/
EFI_STATUS
ReleaseCacheList (
  IN  REDFISH_HTTP_CACHE_LIST  *CacheList
  )
{
  LIST_ENTRY               *List;
  LIST_ENTRY               *Next;
  REDFISH_HTTP_CACHE_DATA  *Data;

  if (CacheList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (IsListEmpty (&CacheList->Head)) {
    return EFI_SUCCESS;
  }

  Data = NULL;
  Next = NULL;
  List = GetFirstNode (&CacheList->Head);
  while (!IsNull (&CacheList->Head, List)) {
    Data = REDFISH_HTTP_CACHE_FROM_LIST (List);
    Next = GetNextNode (&CacheList->Head, List);

    DeleteHttpCacheData (CacheList, Data);

    List = Next;
  }

  return EFI_SUCCESS;
}
