/** @file
  The common code of EDKII Redfish Configuration Handler driver.

  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "RedfishConfigHandlerCommon.h"

REDFISH_CONFIG_DRIVER_DATA  gRedfishConfigData;     // Only one Redfish service supproted
                                                    // 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 faied 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 faied 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_INFO, "%a: No Redfish Credential Protocol is installed on system.", __FUNCTION__));
    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.", __FUNCTION__));
    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.", __FUNCTION__));
    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 (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
    return Status;
  }

  Status = EFI_SUCCESS;
  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;
    }
  }

  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));
    }

    //
    // 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);
  }
}
