/** @file
  RestExDxe support functions implementation.

  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
  Copyright (c) 2023, American Megatrends International LLC.
  Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/
#include <Uefi.h>
#include "RedfishRestExInternal.h"

/**
  Create a new TLS session because the previous one is closed.

  @param[in]  Instance            Pointer to EFI_REST_EX_PROTOCOL instance for a particular
                                  REST service.
  @retval EFI_SUCCESS             operation succeeded.
  @retval EFI_ERROR               Other errors.

**/
EFI_STATUS
ResetHttpTslSession (
  IN   RESTEX_INSTANCE  *Instance
  )
{
  EFI_STATUS  Status;

  DEBUG ((DEBUG_MANAGEABILITY, "%a: TCP connection is finished. Could be TSL session closure, reset HTTP instance for the new TLS session.\n", __func__));

  Status = Instance->HttpIo.Http->Configure (Instance->HttpIo.Http, NULL);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Error to reset HTTP instance.\n", __func__));
    return Status;
  }

  Status = Instance->HttpIo.Http->Configure (Instance->HttpIo.Http, &((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Error to re-initiate HTTP instance.\n", __func__));
  }

  return Status;
}

/**
  This function check Http receive status.

  @param[in]  Instance             Pointer to EFI_REST_EX_PROTOCOL instance for a particular
                                   REST service.
  @param[in]  HttpIoReceiveStatus  This is the status return from HttpIoRecvResponse

  @retval EFI_SUCCESS           The payload receive from Redfish service in successfully.
  @retval EFI_NOT_READY         May need to resend the HTTP request.
  @retval EFI_DEVICE_ERROR      Something wrong and can't be resolved.
  @retval Others                Other errors as indicated.

**/
EFI_STATUS
RedfishCheckHttpReceiveStatus (
  IN RESTEX_INSTANCE  *Instance,
  IN EFI_STATUS       HttpIoReceiveStatus
  )
{
  EFI_STATUS  Status;
  EFI_STATUS  ReturnStatus;

  if (!EFI_ERROR (HttpIoReceiveStatus)) {
    ReturnStatus = EFI_SUCCESS;
  } else if (HttpIoReceiveStatus != EFI_CONNECTION_FIN) {
    if ((Instance->Flags & RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY) == 0) {
      DEBUG ((DEBUG_ERROR, "%a: TCP error, reset HTTP session.\n", __func__));
      Instance->Flags |= RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY;
      gBS->Stall (500);
      Status = ResetHttpTslSession (Instance);
      if (!EFI_ERROR (Status)) {
        return EFI_NOT_READY;
      }

      DEBUG ((DEBUG_ERROR, "%a: Reset HTTP instance fail.\n", __func__));
    }

    ReturnStatus = EFI_DEVICE_ERROR;
  } else {
    if ((Instance->Flags & RESTEX_INSTANCE_FLAGS_TLS_RETRY) != 0) {
      DEBUG ((DEBUG_ERROR, "%a: REST_EX Send and receive fail even with a new TLS session.\n", __func__));
      ReturnStatus = EFI_DEVICE_ERROR;
    }

    Instance->Flags |= RESTEX_INSTANCE_FLAGS_TLS_RETRY;
    Status           = ResetHttpTslSession (Instance);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a: Reset HTTP instance fail.\n", __func__));
      ReturnStatus = EFI_DEVICE_ERROR;
    }

    return EFI_NOT_READY;
  }

  //
  // Clean TLS new session retry and error try flags.
  //
  Instance->Flags &= ~(RESTEX_INSTANCE_FLAGS_TLS_RETRY | RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY);
  return ReturnStatus;
}

/**
  This function send the HTTP request without body to see
  if the write to URL is permitted by Redfish service. This function
  checks if the HTTP request has Content-length in HTTP header. If yes,
  set HTTP body to NULL and then send to service. Check the HTTP status
  for the firther actions.

  @param[in]  This                    Pointer to EFI_REST_EX_PROTOCOL instance for a particular
                                      REST service.
  @param[in]  RequestMessage          Pointer to the HTTP request data for this resource
  @param[in]  PreservedRequestHeaders The pointer to save the request headers
  @param[in]  ItsWrite                This is write method to URL.

  @retval EFI_INVALID_PARAMETER  Improper given parameters.
  @retval EFI_SUCCESS            This HTTP request is free to send to Redfish service.
  @retval EFI_OUT_OF_RESOURCES   NOt enough memory to process.
  @retval EFI_ACCESS_DENIED      Not allowed to write to this URL.

  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
RedfishHttpAddExpectation (
  IN EFI_REST_EX_PROTOCOL  *This,
  IN EFI_HTTP_MESSAGE      *RequestMessage,
  IN EFI_HTTP_HEADER       **PreservedRequestHeaders,
  IN BOOLEAN               *ItsWrite
  )
{
  EFI_HTTP_HEADER  *NewHeaders;

  if ((This == NULL) || (RequestMessage == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *ItsWrite = FALSE;

  if ((RequestMessage->Data.Request->Method != HttpMethodPut) && (RequestMessage->Data.Request->Method != HttpMethodPost) &&
      (RequestMessage->Data.Request->Method != HttpMethodPatch))
  {
    return EFI_SUCCESS;
  }

  *ItsWrite = TRUE;

  //
  // Check PCD before adding Expect header
  //
  if (FixedPcdGetBool (PcdRedfishRestExAddingExpect)) {
    if (PreservedRequestHeaders != NULL) {
      *PreservedRequestHeaders = RequestMessage->Headers;
    }

    NewHeaders = AllocateZeroPool ((RequestMessage->HeaderCount + 1) * sizeof (EFI_HTTP_HEADER));
    CopyMem ((VOID *)NewHeaders, (VOID *)RequestMessage->Headers, RequestMessage->HeaderCount * sizeof (EFI_HTTP_HEADER));
    HttpSetFieldNameAndValue (NewHeaders + RequestMessage->HeaderCount, HTTP_HEADER_EXPECT, HTTP_EXPECT_100_CONTINUE);
    RequestMessage->HeaderCount++;
    RequestMessage->Headers = NewHeaders;
  }

  return EFI_SUCCESS;
}
