/** @file
  The common code of EDKII Redfish Configuration Handler driver.

  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
  Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "RedfishConfigHandlerCommon.h"

REDFISH_CONFIG_DRIVER_DATA  gRedfishConfigData;     // Only one Redfish service supported
                                                    // on platform for the BIOS
                                                    // Redfish configuration.
EFI_EVENT                          gEndOfDxeEvent        = NULL;
EFI_EVENT                          gExitBootServiceEvent = NULL;
EDKII_REDFISH_CREDENTIAL_PROTOCOL  *gCredential          = NULL;

/**
  Callback function executed when the EndOfDxe event group is signaled.

  @param[in]   Event    Event whose notification function is being invoked.
  @param[out]  Context  Pointer to the Context buffer.

**/
VOID
EFIAPI
RedfishConfigOnEndOfDxe (
  IN  EFI_EVENT  Event,
  OUT VOID       *Context
  )
{
  EFI_STATUS  Status;

  Status = gCredential->StopService (gCredential, ServiceStopTypeSecureBootDisabled);
  if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) {
    DEBUG ((DEBUG_ERROR, "Redfish credential protocol failed to stop service on EndOfDxe: %r", Status));
  }

  //
  // Close event, so it will not be invoked again.
  //
  gBS->CloseEvent (gEndOfDxeEvent);
  gEndOfDxeEvent = NULL;
}

/**
  Callback function executed when the ExitBootService event group is signaled.

  @param[in]   Event    Event whose notification function is being invoked.
  @param[out]  Context  Pointer to the Context buffer

**/
VOID
EFIAPI
RedfishConfigOnExitBootService (
  IN  EFI_EVENT  Event,
  OUT VOID       *Context
  )
{
  EFI_STATUS  Status;

  Status = gCredential->StopService (gCredential, ServiceStopTypeExitBootService);
  if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) {
    DEBUG ((DEBUG_ERROR, "Redfish credential protocol failed to stop service on ExitBootService: %r", Status));
  }
}

/**
  Unloads an image.

  @param[in]  ImageHandle       Handle that identifies the image to be unloaded.

  @retval EFI_SUCCESS           The image has been unloaded.

**/
EFI_STATUS
RedfishConfigDriverCommonUnload (
  IN EFI_HANDLE  ImageHandle
  )
{
  if (gEndOfDxeEvent != NULL) {
    gBS->CloseEvent (gEndOfDxeEvent);
    gEndOfDxeEvent = NULL;
  }

  if (gExitBootServiceEvent != NULL) {
    gBS->CloseEvent (gExitBootServiceEvent);
    gExitBootServiceEvent = NULL;
  }

  if (gRedfishConfigData.Event != NULL) {
    gBS->CloseEvent (gRedfishConfigData.Event);
    gRedfishConfigData.Event = NULL;
  }

  return EFI_SUCCESS;
}

/**
  This is the common code for Redfish configuration UEFI and DXE driver
  initialization.

  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
  @param[in]  SystemTable       A pointer to the EFI System Table.

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval Others                An unexpected error occurred.
**/
EFI_STATUS
RedfishConfigCommonInit (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Locate Redfish Credential Protocol to get credential for
  // accessing to Redfish service.
  //
  Status = gBS->LocateProtocol (&gEdkIIRedfishCredentialProtocolGuid, NULL, (VOID **)&gCredential);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: No Redfish Credential Protocol is installed on system.", __func__));
    return Status;
  }

  //
  // Create EndOfDxe Event.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  RedfishConfigOnEndOfDxe,
                  NULL,
                  &gEfiEndOfDxeEventGroupGuid,
                  &gEndOfDxeEvent
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Fail to register End Of DXE event.", __func__));
    return Status;
  }

  //
  // Create Exit Boot Service event.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  RedfishConfigOnExitBootService,
                  NULL,
                  &gEfiEventExitBootServicesGuid,
                  &gExitBootServiceEvent
                  );
  if (EFI_ERROR (Status)) {
    gBS->CloseEvent (gEndOfDxeEvent);
    gEndOfDxeEvent = NULL;
    DEBUG ((DEBUG_ERROR, "%a: Fail to register Exit Boot Service event.", __func__));
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  This is the common code to stop EDK2 Redfish feature driver.

  @retval EFI_SUCCESS    All EDK2 Redfish feature drivers are
                         stopped.
  @retval Others         An unexpected error occurred.
**/
EFI_STATUS
RedfishConfigCommonStop (
  VOID
  )
{
  EFI_STATUS                             Status;
  EFI_HANDLE                             *HandleBuffer;
  UINTN                                  NumberOfHandles;
  UINTN                                  Index;
  EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL  *ConfigHandler;

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEdkIIRedfishConfigHandlerProtocolGuid,
                  NULL,
                  &NumberOfHandles,
                  &HandleBuffer
                  );
  if (Status == EFI_NOT_FOUND) {
    return EFI_SUCCESS;
  } else if (EFI_ERROR (Status)) {
    return Status;
  }

  for (Index = 0; Index < NumberOfHandles; Index++) {
    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEdkIIRedfishConfigHandlerProtocolGuid,
                    (VOID **)&ConfigHandler
                    );
    ASSERT_EFI_ERROR (Status);

    Status = ConfigHandler->Stop (ConfigHandler);
    if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) {
      DEBUG ((DEBUG_ERROR, "ERROR: Failed to stop Redfish config handler %p.\n", ConfigHandler));
      break;
    }
  }

  gBS->FreePool (HandleBuffer);

  return Status;
}

/**
  Callback function executed when a Redfish Config Handler Protocol is installed
  by EDK2 Redfish Feature Drivers.

**/
VOID
RedfishConfigHandlerInitialization (
  VOID
  )
{
  EFI_STATUS                             Status;
  EFI_HANDLE                             *HandleBuffer;
  UINTN                                  NumberOfHandles;
  EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL  *ConfigHandler;
  UINTN                                  Index;
  UINT32                                 *Id;

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEdkIIRedfishConfigHandlerProtocolGuid,
                  NULL,
                  &NumberOfHandles,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return;
  }

  for (Index = 0; Index < NumberOfHandles; Index++) {
    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEfiCallerIdGuid,
                    (VOID **)&Id
                    );
    if (!EFI_ERROR (Status)) {
      continue;
    }

    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEdkIIRedfishConfigHandlerProtocolGuid,
                    (VOID **)&ConfigHandler
                    );
    ASSERT_EFI_ERROR (Status);
    Status = ConfigHandler->Init (ConfigHandler, &gRedfishConfigData.RedfishServiceInfo);
    if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
      DEBUG ((DEBUG_ERROR, "ERROR: Failed to init Redfish config handler %p.\n", ConfigHandler));
      continue;
    }

    //
    // Install caller ID to indicate Redfish Configure Handler is initialized.
    //
    Status = gBS->InstallProtocolInterface (
                    &HandleBuffer[Index],
                    &gEfiCallerIdGuid,
                    EFI_NATIVE_INTERFACE,
                    (VOID *)&gRedfishConfigData.CallerId
                    );
    ASSERT_EFI_ERROR (Status);
  }

  gBS->FreePool (HandleBuffer);
}
