/** @file
*
*  Copyright (c) 2012-2014, 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 <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>

#include <Protocol/DevicePathFromText.h>
#include <Protocol/DriverBinding.h>

#include "BootMonFsInternal.h"

EFI_DEVICE_PATH* mBootMonFsSupportedDevicePaths;
LIST_ENTRY       mInstances;

EFI_FILE_PROTOCOL mBootMonFsRootTemplate = {
  EFI_FILE_PROTOCOL_REVISION,
  BootMonFsOpenFile,
  BootMonFsCloseFile,
  BootMonFsDeleteFail,
  BootMonFsReadDirectory,
  BootMonFsWriteFile,
  BootMonFsGetPositionUnsupported,  // UEFI Spec: GetPosition not valid on dirs
  BootMonFsSetDirPosition,
  BootMonFsGetInfo,
  BootMonFsSetInfo,
  BootMonFsFlushDirectory
};

EFI_FILE_PROTOCOL mBootMonFsFileTemplate = {
  EFI_FILE_PROTOCOL_REVISION,
  BootMonFsOpenFile,
  BootMonFsCloseFile,
  BootMonFsDelete,
  BootMonFsReadFile,
  BootMonFsWriteFile,
  BootMonFsGetPosition,
  BootMonFsSetPosition,
  BootMonFsGetInfo,
  BootMonFsSetInfo,
  BootMonFsFlushFile
};

/**
  Search for a file given its name coded in Ascii.

  When searching through the files of the volume, if a file is currently not
  open, its name was written on the media and is kept in RAM in the
  "HwDescription.Footer.Filename[]" field of the file's description.

  If a file is currently open, its name might not have been written on the
  media yet, and as the "HwDescription" is a mirror in RAM of what is on the
  media the "HwDescription.Footer.Filename[]" might be outdated. In that case,
  the up to date name of the file is stored in the "Info" field of the file's
  description.

  @param[in]   Instance       Pointer to the description of the volume in which
                              the file has to be search for.
  @param[in]   AsciiFileName  Name of the file.

  @param[out]  File           Pointer to the description of the file if the
                              file was found.

  @retval  EFI_SUCCESS    The file was found.
  @retval  EFI_NOT_FOUND  The file was not found.

**/
EFI_STATUS
BootMonGetFileFromAsciiFileName (
  IN  BOOTMON_FS_INSTANCE   *Instance,
  IN  CHAR8*                AsciiFileName,
  OUT BOOTMON_FS_FILE       **File
  )
{
  LIST_ENTRY       *Entry;
  BOOTMON_FS_FILE  *FileEntry;
  CHAR8            OpenFileAsciiFileName[MAX_NAME_LENGTH];
  CHAR8            *AsciiFileNameToCompare;

  // Go through all the files in the list and return the file handle
  for (Entry = GetFirstNode (&Instance->RootFile->Link);
       !IsNull (&Instance->RootFile->Link, Entry);
       Entry = GetNextNode (&Instance->RootFile->Link, Entry)
       )
  {
    FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (Entry);
    if (FileEntry->Info != NULL) {
      UnicodeStrToAsciiStrS (FileEntry->Info->FileName, OpenFileAsciiFileName,
        MAX_NAME_LENGTH);
      AsciiFileNameToCompare = OpenFileAsciiFileName;
    } else {
      AsciiFileNameToCompare = FileEntry->HwDescription.Footer.Filename;
    }

    if (AsciiStrCmp (AsciiFileNameToCompare, AsciiFileName) == 0) {
      *File = FileEntry;
      return EFI_SUCCESS;
    }
  }
  return EFI_NOT_FOUND;
}

EFI_STATUS
BootMonGetFileFromPosition (
  IN  BOOTMON_FS_INSTANCE   *Instance,
  IN  UINTN                 Position,
  OUT BOOTMON_FS_FILE       **File
  )
{
  LIST_ENTRY        *Entry;
  BOOTMON_FS_FILE   *FileEntry;

  // Go through all the files in the list and return the file handle
  for (Entry = GetFirstNode (&Instance->RootFile->Link);
       !IsNull (&Instance->RootFile->Link, Entry) && (&Instance->RootFile->Link != Entry);
       Entry = GetNextNode (&Instance->RootFile->Link, Entry)
       )
  {
    if (Position == 0) {
      FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (Entry);
      *File = FileEntry;
      return EFI_SUCCESS;
    }
    Position--;
  }
  return EFI_NOT_FOUND;
}

EFI_STATUS
BootMonFsCreateFile (
  IN  BOOTMON_FS_INSTANCE *Instance,
  OUT BOOTMON_FS_FILE     **File
  )
{
  BOOTMON_FS_FILE *NewFile;

  NewFile = (BOOTMON_FS_FILE*)AllocateZeroPool (sizeof (BOOTMON_FS_FILE));
  if (NewFile == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  NewFile->Signature = BOOTMON_FS_FILE_SIGNATURE;
  InitializeListHead (&NewFile->Link);
  InitializeListHead (&NewFile->RegionToFlushLink);
  NewFile->Instance = Instance;

  // If the created file is the root file then create a directory EFI_FILE_PROTOCOL
  if (Instance->RootFile == *File) {
    CopyMem (&NewFile->File, &mBootMonFsRootTemplate, sizeof (mBootMonFsRootTemplate));
  } else {
    CopyMem (&NewFile->File, &mBootMonFsFileTemplate, sizeof (mBootMonFsFileTemplate));
  }
  *File = NewFile;
  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
SupportedDevicePathsInit (
  VOID
  )
{
  EFI_STATUS                          Status;
  CHAR16*                             DevicePathListStr;
  CHAR16*                             DevicePathStr;
  CHAR16*                             NextDevicePathStr;
  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
  EFI_DEVICE_PATH_PROTOCOL           *Instance;

  Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
  ASSERT_EFI_ERROR (Status);

  // Initialize Variable
  DevicePathListStr = (CHAR16*)PcdGetPtr (PcdBootMonFsSupportedDevicePaths);
  mBootMonFsSupportedDevicePaths = NULL;

  // Extract the Device Path instances from the multi-device path string
  while ((DevicePathListStr != NULL) && (DevicePathListStr[0] != L'\0')) {
    NextDevicePathStr = StrStr (DevicePathListStr, L";");
    if (NextDevicePathStr == NULL) {
      DevicePathStr = DevicePathListStr;
      DevicePathListStr = NULL;
    } else {
      DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DevicePathListStr + 1) * sizeof (CHAR16), DevicePathListStr);
      if (DevicePathStr == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
      *(DevicePathStr + (NextDevicePathStr - DevicePathListStr)) = L'\0';
      DevicePathListStr = NextDevicePathStr;
      if (DevicePathListStr[0] == L';') {
        DevicePathListStr++;
      }
    }

    Instance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr);
    ASSERT (Instance != NULL);
    mBootMonFsSupportedDevicePaths = AppendDevicePathInstance (mBootMonFsSupportedDevicePaths, Instance);

    if (NextDevicePathStr != NULL) {
      FreePool (DevicePathStr);
    }
    FreePool (Instance);
  }

  if (mBootMonFsSupportedDevicePaths == NULL) {
    return EFI_UNSUPPORTED;
  } else {
    return EFI_SUCCESS;
  }
}

EFI_STATUS
EFIAPI
BootMonFsDriverSupported (
  IN        EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
  IN        EFI_HANDLE                   ControllerHandle,
  IN        EFI_DEVICE_PATH_PROTOCOL    *DevicePath OPTIONAL
  )
{
  EFI_DISK_IO_PROTOCOL  *DiskIo;
  EFI_DEVICE_PATH_PROTOCOL *DevicePathProtocol;
  EFI_DEVICE_PATH_PROTOCOL *SupportedDevicePath;
  EFI_DEVICE_PATH_PROTOCOL *SupportedDevicePaths;
  EFI_STATUS Status;
  UINTN Size1;
  UINTN Size2;

  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDiskIoProtocolGuid,
                  (VOID **) &DiskIo,
                  gImageHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Close the I/O Abstraction(s) used to perform the supported test
  //
  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiDiskIoProtocolGuid,
         gImageHandle,
         ControllerHandle
         );

  // Check that BlockIo protocol instance exists
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiBlockIoProtocolGuid,
                  NULL,
                  gImageHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // Check if a DevicePath is attached to the handle
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&DevicePathProtocol,
                  gImageHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // Check if the Device Path is the one which contains the Boot Monitor File System
  Size1 = GetDevicePathSize (DevicePathProtocol);

  // Go through the list of Device Path Instances
  Status = EFI_UNSUPPORTED;
  SupportedDevicePaths = mBootMonFsSupportedDevicePaths;
  while (SupportedDevicePaths != NULL) {
    SupportedDevicePath = GetNextDevicePathInstance (&SupportedDevicePaths, &Size2);

    if ((Size1 == Size2) && (CompareMem (DevicePathProtocol, SupportedDevicePath, Size1) == 0)) {
      // The Device Path is supported
      Status = EFI_SUCCESS;
      break;
    }
  }

  gBS->CloseProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, gImageHandle, ControllerHandle);
  return Status;
}

EFI_STATUS
EFIAPI
BootMonFsDriverStart (
  IN        EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
  IN        EFI_HANDLE                   ControllerHandle,
  IN        EFI_DEVICE_PATH_PROTOCOL    *DevicePath OPTIONAL
  )
{
  BOOTMON_FS_INSTANCE *Instance;
  EFI_STATUS           Status;
  UINTN                VolumeNameSize;
  EFI_FILE_INFO       *Info;

  Instance = AllocateZeroPool (sizeof (BOOTMON_FS_INSTANCE));
  if (Instance == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  // Initialize the BlockIo of the Instance
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **)&(Instance->BlockIo),
                  gImageHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDiskIoProtocolGuid,
                  (VOID **)&(Instance->DiskIo),
                  gImageHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  //
  // Initialize the attributes of the Instance
  //
  Instance->Signature = BOOTMON_FS_SIGNATURE;
  Instance->ControllerHandle = ControllerHandle;
  Instance->Media = Instance->BlockIo->Media;
  Instance->Binding = DriverBinding;

    // Initialize the Simple File System Protocol
  Instance->Fs.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
  Instance->Fs.OpenVolume = OpenBootMonFsOpenVolume;

  // Volume name + L' ' + '2' digit number
  VolumeNameSize = StrSize (BOOTMON_FS_VOLUME_LABEL) + (3 * sizeof (CHAR16));

  // Initialize FileSystem Information
  Instance->FsInfo.Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + VolumeNameSize;
  Instance->FsInfo.BlockSize = Instance->Media->BlockSize;
  Instance->FsInfo.ReadOnly = FALSE;
  Instance->FsInfo.VolumeSize =
    Instance->Media->BlockSize * (Instance->Media->LastBlock - Instance->Media->LowestAlignedLba);
  CopyMem (Instance->FsInfo.VolumeLabel, BOOTMON_FS_VOLUME_LABEL, StrSize (BOOTMON_FS_VOLUME_LABEL));

  // Initialize the root file
  Status = BootMonFsCreateFile (Instance, &Instance->RootFile);
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  Info = AllocateZeroPool (sizeof (EFI_FILE_INFO));
  if (Info == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }
  Instance->RootFile->Info = Info;

  // Initialize the DevicePath of the Instance
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&(Instance->DevicePath),
                  gImageHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  //
  // Install the Simple File System Protocol
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                      &ControllerHandle,
                      &gEfiSimpleFileSystemProtocolGuid, &Instance->Fs,
                      NULL
                      );
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  InsertTailList (&mInstances, &Instance->Link);

  return EFI_SUCCESS;

Error:

    if (Instance->RootFile != NULL) {
      if (Instance->RootFile->Info != NULL) {
        FreePool (Instance->RootFile->Info);
      }
      FreePool (Instance->RootFile);
    }
    FreePool (Instance);

  return Status;
}


EFI_STATUS
EFIAPI
BootMonFsDriverStop (
  IN        EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
  IN        EFI_HANDLE                   ControllerHandle,
  IN        UINTN                        NumberOfChildren,
  IN        EFI_HANDLE                  *ChildHandleBuffer OPTIONAL
  )
{
  BOOTMON_FS_INSTANCE *Instance;
  LIST_ENTRY          *Link;
  EFI_STATUS           Status;
  BOOLEAN              InstanceFound;

  // Find instance from ControllerHandle.
  Instance = NULL;
  InstanceFound = FALSE;
  // For each instance in mInstances:
  for (Link = GetFirstNode (&mInstances); !IsNull (&mInstances, Link); Link = GetNextNode (&mInstances, Link)) {
    Instance = BOOTMON_FS_FROM_LINK (Link);

    if (Instance->ControllerHandle == ControllerHandle) {
      InstanceFound = TRUE;
      break;
    }
  }
  ASSERT (InstanceFound == TRUE);

  gBS->CloseProtocol (
      ControllerHandle,
      &gEfiDevicePathProtocolGuid,
      DriverBinding->ImageHandle,
      ControllerHandle);

  gBS->CloseProtocol (
      ControllerHandle,
      &gEfiDiskIoProtocolGuid,
      DriverBinding->ImageHandle,
      ControllerHandle);

  gBS->CloseProtocol (
      ControllerHandle,
      &gEfiBlockIoProtocolGuid,
      DriverBinding->ImageHandle,
      ControllerHandle);

  Status = gBS->UninstallMultipleProtocolInterfaces (
      &ControllerHandle,
      &gEfiSimpleFileSystemProtocolGuid, &Instance->Fs,
      NULL);

  FreePool (Instance->RootFile->Info);
  FreePool (Instance->RootFile);
  FreePool (Instance);

  return Status;
}

//
// Simple Network Protocol Driver Global Variables
//
EFI_DRIVER_BINDING_PROTOCOL mBootMonFsDriverBinding = {
  BootMonFsDriverSupported,
  BootMonFsDriverStart,
  BootMonFsDriverStop,
  0xa,
  NULL,
  NULL
};

EFI_STATUS
EFIAPI
BootMonFsEntryPoint (
  IN EFI_HANDLE                            ImageHandle,
  IN EFI_SYSTEM_TABLE                      *SystemTable
  )
{
  EFI_STATUS  Status;

  InitializeListHead (&mInstances);

  // Initialize the list of Device Paths that could support BootMonFs
  Status = SupportedDevicePathsInit ();
  if (!EFI_ERROR (Status)) {
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &ImageHandle,
                    &gEfiDriverBindingProtocolGuid, &mBootMonFsDriverBinding,
                    NULL
                    );
    ASSERT_EFI_ERROR (Status);
  } else {
    DEBUG((EFI_D_ERROR,"Warning: No Device Paths supporting BootMonFs have been defined in the PCD.\n"));
  }

  return Status;
}
