/** @file
*
*  Copyright (c) 2011-2012, ARM Limited. All rights reserved.
*
*  This program and the accompanying materials
*  are licensed and made available under the terms and conditions of the BSD License
*  which accompanies this distribution.  The full text of the license may be found at
*  http://opensource.org/licenses/bsd-license.php
*
*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
**/

#include "BdsInternal.h"

//#include <Library/DxeServicesLib.h>

STATIC
EFI_STATUS
BdsLoadFileFromFirmwareVolume (
  IN  EFI_HANDLE      FvHandle,
  IN  CHAR16    *FilePath,
  IN  EFI_FV_FILETYPE FileTypeFilter,
  OUT EFI_DEVICE_PATH     **EfiAppDevicePath
  )
{
  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
  VOID                          *Key;
  EFI_STATUS                    Status, FileStatus;
  EFI_GUID                      NameGuid;
  EFI_FV_FILETYPE               FileType;
  EFI_FV_FILE_ATTRIBUTES        Attributes;
  UINTN                         Size;
  UINTN                         UiStringLen;
  CHAR16                        *UiSection;
  UINT32                        Authentication;
  EFI_DEVICE_PATH               *FvDevicePath;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH    FileDevicePath;

  Status = gBS->HandleProtocol (FvHandle,&gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FvProtocol);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  // Length of FilePath
  UiStringLen = StrLen (FilePath);

  // Allocate Key
  Key = AllocatePool (FvProtocol->KeySize);
  ASSERT (Key != NULL);
  ZeroMem (Key, FvProtocol->KeySize);

  do {
    // Search in all files
    FileType = FileTypeFilter;

    Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size);
    if (!EFI_ERROR (Status)) {
      UiSection = NULL;
      FileStatus = FvProtocol->ReadSection (
                    FvProtocol,
                    &NameGuid,
                    EFI_SECTION_USER_INTERFACE,
                    0,
                    (VOID **)&UiSection,
                    &Size,
                    &Authentication
                    );
      if (!EFI_ERROR (FileStatus)) {
        if (StrnCmp (FilePath, UiSection, UiStringLen) == 0) {
          //
          // We found a UiString match.
          //
          Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);

          // Generate the Device Path for the file
          //DevicePath = DuplicateDevicePath(FvDevicePath);
          EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);
          *EfiAppDevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);

          FreePool (Key);
          FreePool (UiSection);
          return FileStatus;
        }
        FreePool (UiSection);
      }
    }
  } while (!EFI_ERROR (Status));

  FreePool(Key);
  return Status;
}

/**
  Start an EFI Application from any Firmware Volume

  @param  EfiApp                EFI Application Name

  @retval EFI_SUCCESS           All drivers have been connected
  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found
  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.

**/
EFI_STATUS
BdsLoadApplication (
  IN EFI_HANDLE                  ParentImageHandle,
  IN CHAR16*                     EfiApp,
  IN UINTN                       LoadOptionsSize,
  IN VOID*                       LoadOptions
  )
{
  EFI_STATUS                      Status;
  UINTN                           NoHandles, HandleIndex;
  EFI_HANDLE                      *Handles;
  EFI_DEVICE_PATH                 *EfiAppDevicePath;

  // Need to connect every drivers to ensure no dependencies are missing for the application
  Status = BdsConnectAllDrivers();
  if (EFI_ERROR(Status)) {
    DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));
    return Status;
  }

  // Search the application in any Firmware Volume
  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles);
  if (EFI_ERROR (Status) || (NoHandles == 0)) {
    DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n"));
    return Status;
  }

  // Search in all Firmware Volume for the EFI Application
  for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {
    EfiAppDevicePath = NULL;
    Status = BdsLoadFileFromFirmwareVolume (Handles[HandleIndex], EfiApp, EFI_FV_FILETYPE_APPLICATION, &EfiAppDevicePath);
    if (!EFI_ERROR (Status)) {
      // Start the application
      Status = BdsStartEfiApplication (ParentImageHandle, EfiAppDevicePath, LoadOptionsSize, LoadOptions);
      return Status;
    }
  }

  return Status;
}
