/** @file
  Emulator Thunk to abstract OS services from pure EFI code

  Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.<BR>
  Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>

#include <Protocol/EmuIoThunk.h>

#define EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE  SIGNATURE_32('E','m','u','T')

typedef struct {
  UINTN                    Signature;
  EMU_IO_THUNK_PROTOCOL    Data;
  BOOLEAN                  EmuBusDriver;
  LIST_ENTRY               Link;
} EMU_IO_THUNK_PROTOCOL_DATA;

LIST_ENTRY  mThunkList = INITIALIZE_LIST_HEAD_VARIABLE (mThunkList);

EFI_STATUS
EFIAPI
AddThunkProtocol (
  IN  EMU_IO_THUNK_PROTOCOL  *ThunkIo,
  IN  CHAR16                 *ConfigString,
  IN  BOOLEAN                EmuBusDriver
  )
{
  UINTN                       Size;
  CHAR16                      *StartString;
  CHAR16                      *SubString;
  UINTN                       Instance;
  EMU_IO_THUNK_PROTOCOL_DATA  *Private;

  if (ThunkIo == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance    = 0;
  Size        = StrSize (ConfigString);
  StartString = AllocatePool (Size);
  if (StartString == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  StrCpyS (StartString, Size / sizeof (CHAR16), ConfigString);
  while (*StartString != '\0') {
    //
    // Find the end of the sub string
    //
    SubString = StartString;
    while (*SubString != '\0' && *SubString != '!') {
      SubString++;
    }

    if (*SubString == '!') {
      //
      // Replace token with '\0' to make sub strings. If this is the end
      //  of the string SubString will already point to NULL.
      //
      *SubString = '\0';
      SubString++;
    }

    Private = AllocatePool (sizeof (EMU_IO_THUNK_PROTOCOL_DATA));
    if (Private == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Private->Signature    = EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE;
    Private->EmuBusDriver = EmuBusDriver;

    CopyMem (&Private->Data, ThunkIo, sizeof (EMU_IO_THUNK_PROTOCOL));
    Private->Data.Instance     = (UINT16)Instance++;
    Private->Data.ConfigString = StartString;

    InsertTailList (&mThunkList, &Private->Link);

    //
    // Parse Next sub string. This will point to '\0' if we are at the end.
    //
    StartString = SubString;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
GetNextThunkProtocol (
  IN  BOOLEAN                EmuBusDriver,
  OUT EMU_IO_THUNK_PROTOCOL  **Instance  OPTIONAL
  )
{
  LIST_ENTRY                  *Link;
  EMU_IO_THUNK_PROTOCOL_DATA  *Private;

  if (mThunkList.ForwardLink == &mThunkList) {
    // Skip parsing an empty list
    return EFI_NOT_FOUND;
  }

  for (Link = mThunkList.ForwardLink; Link != &mThunkList; Link = Link->ForwardLink) {
    Private = CR (Link, EMU_IO_THUNK_PROTOCOL_DATA, Link, EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE);
    if (EmuBusDriver & !Private->EmuBusDriver) {
      continue;
    } else if (*Instance == NULL) {
      // Find 1st match in list
      *Instance = &Private->Data;
      return EFI_SUCCESS;
    } else if (*Instance == &Private->Data) {
      // Matched previous call so look for valid next entry
      Link = Link->ForwardLink;
      if (Link == &mThunkList) {
        return EFI_NOT_FOUND;
      }

      Private   = CR (Link, EMU_IO_THUNK_PROTOCOL_DATA, Link, EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE);
      *Instance = &Private->Data;
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}
