/** @file
  The UEFI driver model driver which is responsible for locating the
  Redfish service through Redfish host interface and executing EDKII
  Redfish feature drivers.

  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "RedfishConfigHandlerDriver.h"

EFI_EVENT  gEfiRedfishDiscoverProtocolEvent = NULL;

//
// Variables for using RFI Redfish Discover Protocol
//
VOID                           *gEfiRedfishDiscoverRegistration;
EFI_HANDLE                     gEfiRedfishDiscoverControllerHandle = NULL;
EFI_REDFISH_DISCOVER_PROTOCOL  *gEfiRedfishDiscoverProtocol        = NULL;
BOOLEAN                        gRedfishDiscoverActivated           = FALSE;
BOOLEAN                        gRedfishServiceDiscovered           = FALSE;

///
/// Driver Binding Protocol instance
///
EFI_DRIVER_BINDING_PROTOCOL  gRedfishConfigDriverBinding = {
  RedfishConfigDriverBindingSupported,
  RedfishConfigDriverBindingStart,
  RedfishConfigDriverBindingStop,
  REDFISH_CONFIG_VERSION,
  NULL,
  NULL
};

/**
  Stop acquiring Redfish service.

**/
VOID
RedfishConfigStopRedfishDiscovery (
  VOID
  )
{
  if (gRedfishDiscoverActivated) {
    //
    // No more EFI Discover Protocol.
    //
    if (gEfiRedfishDiscoverProtocolEvent != NULL) {
      gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent);
    }

    gEfiRedfishDiscoverControllerHandle = NULL;
    gEfiRedfishDiscoverProtocol         = NULL;
    gRedfishDiscoverActivated           = FALSE;
    gRedfishServiceDiscovered           = FALSE;
  }
}

/**
  Callback function executed when a Redfish Config Handler Protocol is installed.

  @param[in]  Event    Event whose notification function is being invoked.
  @param[in]  Context  Pointer to the REDFISH_CONFIG_DRIVER_DATA buffer.

**/
VOID
EFIAPI
RedfishConfigHandlerInstalledCallback (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  if (!gRedfishDiscoverActivated) {
    //
    // No Redfish service is discovered yet.
    //
    return;
  }

  RedfishConfigHandlerInitialization ();
}

/**
  Tests to see if this driver supports a given controller. If a child device is provided,
  it further tests to see if this driver supports creating a handle for the specified child device.

  This function checks to see if the driver specified by This supports the device specified by
  ControllerHandle. Drivers will typically use the device path attached to
  ControllerHandle and/or the services from the bus I/O abstraction attached to
  ControllerHandle to determine if the driver supports ControllerHandle. This function
  may be called many times during platform initialization. In order to reduce boot times, the tests
  performed by this function must be very small, and take as little time as possible to execute. This
  function must not change the state of any hardware devices, and this function must be aware that the
  device specified by ControllerHandle may already be managed by the same driver or a
  different driver. This function must match its calls to AllocatePages() with FreePages(),
  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
  Because ControllerHandle may have been previously started by the same driver, if a protocol is
  already in the opened state, then it must not be closed with CloseProtocol(). This is required
  to guarantee the state of ControllerHandle is not modified by this function.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to test. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For bus drivers, if this parameter is not NULL, then
                                   the bus driver must determine if the bus controller specified
                                   by ControllerHandle and the child controller specified
                                   by RemainingDevicePath are both supported by this
                                   bus driver.

  @retval EFI_SUCCESS              The device specified by ControllerHandle and
                                   RemainingDevicePath is supported by the driver specified by This.
  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
                                   RemainingDevicePath is not supported by the driver specified by This.
**/
EFI_STATUS
EFIAPI
RedfishConfigDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_REST_EX_PROTOCOL  *RestEx;
  EFI_STATUS            Status;
  EFI_HANDLE            ChildHandle;

  ChildHandle = NULL;

  //
  // Check if REST EX is ready. This just makes sure
  // the network stack is brought up.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             This->ImageHandle,
             &gEfiRestExServiceBindingProtocolGuid,
             &ChildHandle
             );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  //
  // Test if REST EX protocol is ready.
  //
  Status = gBS->OpenProtocol (
                  ChildHandle,
                  &gEfiRestExProtocolGuid,
                  (VOID **)&RestEx,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    Status = EFI_UNSUPPORTED;
  }

  NetLibDestroyServiceChild (
    ControllerHandle,
    This->ImageHandle,
    &gEfiRestExServiceBindingProtocolGuid,
    ChildHandle
    );
  return Status;
}

/**
  Starts a device controller or a bus controller.

  The Start() function is designed to be invoked from the EFI boot service ConnectController().
  As a result, much of the error checking on the parameters to Start() has been moved into this
  common boot service. It is legal to call Start() from other locations,
  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE.
  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
     EFI_DEVICE_PATH_PROTOCOL.
  3. Prior to calling Start(), the Supported() function for the driver specified by This must
     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to start. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For a bus driver, if this parameter is NULL, then handles
                                   for all the children of Controller are created by this driver.
                                   If this parameter is not NULL and the first Device Path Node is
                                   not the End of Device Path Node, then only the handle for the
                                   child device specified by the first Device Path Node of
                                   RemainingDevicePath is created by this driver.
                                   If the first Device Path Node of RemainingDevicePath is
                                   the End of Device Path Node, no child handle is created by this
                                   driver.

  @retval EFI_SUCCESS              The driver is started.
  @retval EFI_ALREADY_STARTED      The driver was already started.

**/
EFI_STATUS
EFIAPI
RedfishConfigDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  VOID  *ConfigHandlerRegistration;

  if (gRedfishConfigData.Event != NULL) {
    return EFI_ALREADY_STARTED;
  }

  gRedfishConfigData.Event = EfiCreateProtocolNotifyEvent (
                               &gEdkIIRedfishConfigHandlerProtocolGuid,
                               TPL_CALLBACK,
                               RedfishConfigHandlerInstalledCallback,
                               (VOID *)&gRedfishConfigData,
                               &ConfigHandlerRegistration
                               );
  return EFI_SUCCESS;
}

/**
  Stops a device controller or a bus controller.

  The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
  As a result, much of the error checking on the parameters to Stop() has been moved
  into this common boot service. It is legal to call Stop() from other locations,
  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
     same driver's Start() function.
  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
     EFI_HANDLE. In addition, all of these handles must have been created in this driver's
     Start() function, and the Start() function must have called OpenProtocol() on
     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.

  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
                                support a bus specific I/O protocol for the driver
                                to use to stop the device.
  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
                                if NumberOfChildren is 0.

  @retval EFI_SUCCESS           The device was stopped.
  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.

**/
EFI_STATUS
EFIAPI
RedfishConfigDriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
  )
{
  EFI_STATUS  Status;

  if (ControllerHandle == gEfiRedfishDiscoverControllerHandle) {
    RedfishConfigStopRedfishDiscovery ();
  }

  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiRedfishDiscoverProtocolGuid,
         gRedfishConfigData.Image,
         gRedfishConfigData.Image
         );

  Status = RedfishConfigCommonStop ();
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  if (gRedfishConfigData.Event != NULL) {
    gBS->CloseEvent (gRedfishConfigData.Event);
    gRedfishConfigData.Event = NULL;
  }

  return EFI_SUCCESS;
}

/**
  Callback function when Redfish service is discovered.

  @param[in]   Event    Event whose notification function is being invoked.
  @param[out]  Context  Pointer to the Context buffer

**/
VOID
EFIAPI
RedfishServiceDiscoveredCallback (
  IN  EFI_EVENT  Event,
  OUT VOID       *Context
  )
{
  EFI_REDFISH_DISCOVERED_TOKEN     *RedfishDiscoveredToken;
  EFI_REDFISH_DISCOVERED_INSTANCE  *RedfishInstance;

  RedfishDiscoveredToken = (EFI_REDFISH_DISCOVERED_TOKEN *)Context;
  gBS->CloseEvent (RedfishDiscoveredToken->Event);

  //
  // Only support one Redfish service on platform.
  //
  if (!gRedfishServiceDiscovered) {
    RedfishInstance = RedfishDiscoveredToken->DiscoverList.RedfishInstances;
    //
    // Only pick up the first found Redfish service.
    //
    if (RedfishInstance->Status == EFI_SUCCESS) {
      gRedfishConfigData.RedfishServiceInfo.RedfishServiceRestExHandle = RedfishInstance->Information.RedfishRestExHandle;
      gRedfishConfigData.RedfishServiceInfo.RedfishServiceVersion      = RedfishInstance->Information.RedfishVersion;
      gRedfishConfigData.RedfishServiceInfo.RedfishServiceLocation     = RedfishInstance->Information.Location;
      gRedfishConfigData.RedfishServiceInfo.RedfishServiceUuid         = RedfishInstance->Information.Uuid;
      gRedfishConfigData.RedfishServiceInfo.RedfishServiceOs           = RedfishInstance->Information.Os;
      gRedfishConfigData.RedfishServiceInfo.RedfishServiceOsVersion    = RedfishInstance->Information.OsVersion;
      gRedfishConfigData.RedfishServiceInfo.RedfishServiceProduct      = RedfishInstance->Information.Product;
      gRedfishConfigData.RedfishServiceInfo.RedfishServiceProductVer   = RedfishInstance->Information.ProductVer;
      gRedfishConfigData.RedfishServiceInfo.RedfishServiceUseHttps     = RedfishInstance->Information.UseHttps;
      gRedfishServiceDiscovered                                        = TRUE;
    }

    //
    // Invoke RedfishConfigHandlerInstalledCallback to execute
    // the initialization of Redfish Configure Handler instance.
    //
    RedfishConfigHandlerInstalledCallback (gRedfishConfigData.Event, &gRedfishConfigData);
  }

  FreePool (RedfishDiscoveredToken);
}

/**
  Callback function executed when the EFI_REDFISH_DISCOVER_PROTOCOL
  protocol interface is installed.

  @param[in]   Event    Event whose notification function is being invoked.
  @param[out]  Context  Pointer to the Context buffer

**/
VOID
EFIAPI
RedfishDiscoverProtocolInstalled (
  IN  EFI_EVENT  Event,
  OUT VOID       *Context
  )
{
  EFI_STATUS                              Status;
  UINTN                                   BufferSize;
  EFI_HANDLE                              HandleBuffer;
  UINTN                                   NetworkInterfaceIndex;
  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE  *ThisNetworkInterface;
  EFI_REDFISH_DISCOVERED_TOKEN            *ThisRedfishDiscoveredToken;
  UINTN                                   NumberOfNetworkInterfaces;

  DEBUG ((DEBUG_MANAGEABILITY, "%a: New network interface is installed on system by EFI Redfish discover driver.\n", __func__));

  BufferSize = sizeof (EFI_HANDLE);
  Status     = gBS->LocateHandle (
                      ByRegisterNotify,
                      NULL,
                      gEfiRedfishDiscoverRegistration,
                      &BufferSize,
                      &HandleBuffer
                      );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Can't locate handle with EFI_REDFISH_DISCOVER_PROTOCOL installed.\n", __func__));
  }

  gRedfishDiscoverActivated = TRUE;
  if (gEfiRedfishDiscoverProtocol == NULL) {
    gEfiRedfishDiscoverControllerHandle = HandleBuffer;
    //
    // First time to open EFI_REDFISH_DISCOVER_PROTOCOL.
    //
    Status = gBS->OpenProtocol (
                    gEfiRedfishDiscoverControllerHandle,
                    &gEfiRedfishDiscoverProtocolGuid,
                    (VOID **)&gEfiRedfishDiscoverProtocol,
                    gRedfishConfigData.Image,
                    gRedfishConfigData.Image,
                    EFI_OPEN_PROTOCOL_BY_DRIVER
                    );
    if (EFI_ERROR (Status)) {
      gEfiRedfishDiscoverProtocol = NULL;
      gRedfishDiscoverActivated   = FALSE;
      DEBUG ((DEBUG_ERROR, "%a: Can't locate EFI_REDFISH_DISCOVER_PROTOCOL.\n", __func__));
      return;
    }
  }

  Status = gEfiRedfishDiscoverProtocol->GetNetworkInterfaceList (
                                          gEfiRedfishDiscoverProtocol,
                                          gRedfishConfigData.Image,
                                          &NumberOfNetworkInterfaces,
                                          &ThisNetworkInterface
                                          );
  if (EFI_ERROR (Status) || (NumberOfNetworkInterfaces == 0)) {
    DEBUG ((DEBUG_ERROR, "%a: No network interfaces found on the handle.\n", __func__));
    return;
  }

  //
  // Loop to discover Redfish service on each network interface.
  //
  for (NetworkInterfaceIndex = 0; NetworkInterfaceIndex < NumberOfNetworkInterfaces; NetworkInterfaceIndex++) {
    ThisRedfishDiscoveredToken = (EFI_REDFISH_DISCOVERED_TOKEN *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_TOKEN));
    if (ThisRedfishDiscoveredToken == NULL) {
      DEBUG ((DEBUG_ERROR, "%a: Not enough memory for EFI_REDFISH_DISCOVERED_TOKEN.\n", __func__));
      return;
    }

    ThisRedfishDiscoveredToken->Signature = REDFISH_DISCOVER_TOKEN_SIGNATURE;

    //
    // Initial this Redfish Discovered Token
    //
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_CALLBACK,
                    RedfishServiceDiscoveredCallback,
                    (VOID *)ThisRedfishDiscoveredToken,
                    &ThisRedfishDiscoveredToken->Event
                    );
    if (EFI_ERROR (Status)) {
      FreePool (ThisRedfishDiscoveredToken);
      DEBUG ((DEBUG_ERROR, "%a: Failed to create event for Redfish discovered token.\n", __func__));
      return;
    }

    //
    // Acquire for Redfish service which is reported by
    // Redfish Host Interface.
    //
    Status = gEfiRedfishDiscoverProtocol->AcquireRedfishService (
                                            gEfiRedfishDiscoverProtocol,
                                            gRedfishConfigData.Image,
                                            ThisNetworkInterface,
                                            EFI_REDFISH_DISCOVER_HOST_INTERFACE,
                                            ThisRedfishDiscoveredToken
                                            );

    //
    // Free Redfish Discovered Token if Discover Instance was not created and
    // Redfish Service Discovered Callback event was not triggered.
    //
    if ((ThisRedfishDiscoveredToken->DiscoverList.NumberOfServiceFound == 0) ||
        EFI_ERROR (ThisRedfishDiscoveredToken->DiscoverList.RedfishInstances->Status))
    {
      gBS->CloseEvent (ThisRedfishDiscoveredToken->Event);
      DEBUG ((DEBUG_ERROR, "%a: Free Redfish discovered token - %x.\n", __func__, ThisRedfishDiscoveredToken));
      FreePool (ThisRedfishDiscoveredToken);
    }

    ThisNetworkInterface++;
  }

  return;
}

/**
  Unloads an image.

  @param[in]  ImageHandle       Handle that identifies the image to be unloaded.

  @retval EFI_SUCCESS           The image has been unloaded.

**/
EFI_STATUS
EFIAPI
RedfishConfigHandlerDriverUnload (
  IN EFI_HANDLE  ImageHandle
  )
{
  RedfishConfigDriverCommonUnload (ImageHandle);

  RedfishConfigStopRedfishDiscovery ();

  return EFI_SUCCESS;
}

/**
  This is the declaration of an EFI image entry point. This entry point is
  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
  both device drivers and bus drivers.

  @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
EFIAPI
RedfishConfigHandlerDriverEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  ZeroMem ((VOID *)&gRedfishConfigData, sizeof (REDFISH_CONFIG_DRIVER_DATA));
  gRedfishConfigData.Image = ImageHandle;
  //
  // Register event for EFI_REDFISH_DISCOVER_PROTOCOL protocol install
  // notification.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  RedfishDiscoverProtocolInstalled,
                  NULL,
                  &gEfiRedfishDiscoverProtocolGuid,
                  &gEfiRedfishDiscoverProtocolEvent
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Fail to create event for the installation of EFI_REDFISH_DISCOVER_PROTOCOL.", __func__));
    return Status;
  }

  Status = gBS->RegisterProtocolNotify (
                  &gEfiRedfishDiscoverProtocolGuid,
                  gEfiRedfishDiscoverProtocolEvent,
                  &gEfiRedfishDiscoverRegistration
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: Fail to register event for the installation of EFI_REDFISH_DISCOVER_PROTOCOL.", __func__));
    return Status;
  }

  Status = RedfishConfigCommonInit (ImageHandle, SystemTable);
  if (EFI_ERROR (Status)) {
    gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent);
    gEfiRedfishDiscoverProtocolEvent = NULL;
    return Status;
  }

  //
  // Install UEFI Driver Model protocol(s).
  //
  Status = EfiLibInstallDriverBinding (
             ImageHandle,
             SystemTable,
             &gRedfishConfigDriverBinding,
             ImageHandle
             );
  if (EFI_ERROR (Status)) {
    gBS->CloseEvent (gEndOfDxeEvent);
    gEndOfDxeEvent = NULL;
    gBS->CloseEvent (gExitBootServiceEvent);
    gExitBootServiceEvent = NULL;
    gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent);
    gEfiRedfishDiscoverProtocolEvent = NULL;
    DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI Binding Protocol of EFI Redfish Config driver.", __func__));
    return Status;
  }

  return Status;
}
