/** @file
  Function definitions for shell simple text in and out on top of file handles.

  (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Shell.h"

extern BOOLEAN  AsciiRedirection;

typedef struct {
  EFI_SIMPLE_TEXT_INPUT_PROTOCOL    SimpleTextIn;
  SHELL_FILE_HANDLE                 FileHandle;
  EFI_HANDLE                        TheHandle;
  UINT64                            RemainingBytesOfInputFile;
} SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL;

typedef struct {
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    SimpleTextOut;
  SHELL_FILE_HANDLE                  FileHandle;
  EFI_HANDLE                         TheHandle;
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *OriginalSimpleTextOut;
} SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;

/**
  Event notification function for EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event
  Signal the event if there is key available

  @param  Event                    Indicates the event that invoke this function.
  @param  Context                  Indicates the calling context.

**/
VOID
EFIAPI
ConInWaitForKey (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  gBS->SignalEvent (Event);
}

/**
  Reset function for the fake simple text input.

  @param[in] This     A pointer to the SimpleTextIn structure.
  @param[in] ExtendedVerification TRUE for extra validation, FALSE otherwise.

  @retval   EFI_SUCCESS The reset was successful.
**/
EFI_STATUS
EFIAPI
FileBasedSimpleTextInReset (
  IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,
  IN BOOLEAN                         ExtendedVerification
  )
{
  return (EFI_SUCCESS);
}

/**
  ReadKeyStroke function for the fake simple text input.

  @param[in] This      A pointer to the SimpleTextIn structure.
  @param[in, out] Key  A pointer to the Key structure to fill.

  @retval   EFI_SUCCESS The read was successful.
**/
EFI_STATUS
EFIAPI
FileBasedSimpleTextInReadKeyStroke (
  IN      EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,
  IN OUT  EFI_INPUT_KEY                   *Key
  )
{
  UINTN  Size;
  UINTN  CharSize;

  //
  // Verify the parameters
  //
  if ((Key == NULL) || (This == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Check if we have any characters left in the stream.
  //
  if (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile == 0) {
    return (EFI_NOT_READY);
  }

  Size = sizeof (CHAR16);

  if (!AsciiRedirection) {
    CharSize = sizeof (CHAR16);
  } else {
    CharSize = sizeof (CHAR8);
  }

  //
  // Decrement the amount of free space by Size or set to zero (for odd length files)
  //
  if (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile > CharSize) {
    ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile -= CharSize;
  } else {
    ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile = 0;
  }

  Key->ScanCode = 0;
  return (ShellInfoObject.NewEfiShellProtocol->ReadFile (
                                                 ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->FileHandle,
                                                 &Size,
                                                 &Key->UnicodeChar
                                                 ));
}

/**
  Function to create a EFI_SIMPLE_TEXT_INPUT_PROTOCOL on top of a
  SHELL_FILE_HANDLE to support redirecting input from a file.

  @param[in]  FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.
  @param[in]  HandleLocation  The pointer of a location to copy handle with protocol to.

  @retval NULL                There was insufficient memory available.
  @return                     A pointer to the allocated protocol structure;
**/
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *
CreateSimpleTextInOnFile (
  IN SHELL_FILE_HANDLE  FileHandleToUse,
  IN EFI_HANDLE         *HandleLocation
  )
{
  SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *ProtocolToReturn;
  EFI_STATUS                            Status;
  UINT64                                CurrentPosition;
  UINT64                                FileSize;

  if ((HandleLocation == NULL) || (FileHandleToUse == NULL)) {
    return (NULL);
  }

  ProtocolToReturn = AllocateZeroPool (sizeof (SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL));
  if (ProtocolToReturn == NULL) {
    return (NULL);
  }

  ShellGetFileSize (FileHandleToUse, &FileSize);
  ShellGetFilePosition (FileHandleToUse, &CurrentPosition);

  //
  // Initialize the protocol members
  //
  ProtocolToReturn->RemainingBytesOfInputFile  = FileSize - CurrentPosition;
  ProtocolToReturn->FileHandle                 = FileHandleToUse;
  ProtocolToReturn->SimpleTextIn.Reset         = FileBasedSimpleTextInReset;
  ProtocolToReturn->SimpleTextIn.ReadKeyStroke = FileBasedSimpleTextInReadKeyStroke;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_WAIT,
                  TPL_NOTIFY,
                  ConInWaitForKey,
                  &ProtocolToReturn->SimpleTextIn,
                  &ProtocolToReturn->SimpleTextIn.WaitForKey
                  );

  if (EFI_ERROR (Status)) {
    FreePool (ProtocolToReturn);
    return (NULL);
  }

  /// @todo possibly also install SimpleTextInputEx on the handle at this point.
  Status = gBS->InstallProtocolInterface (
                  &(ProtocolToReturn->TheHandle),
                  &gEfiSimpleTextInProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &(ProtocolToReturn->SimpleTextIn)
                  );
  if (!EFI_ERROR (Status)) {
    *HandleLocation = ProtocolToReturn->TheHandle;
    return ((EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)ProtocolToReturn);
  } else {
    FreePool (ProtocolToReturn);
    return (NULL);
  }
}

/**
  Function to close a EFI_SIMPLE_TEXT_INPUT_PROTOCOL on top of a
  SHELL_FILE_HANDLE to support redirecting input from a file.

  @param[in]  SimpleTextIn    The pointer to the SimpleTextIn to close.

  @retval EFI_SUCCESS         The object was closed.
**/
EFI_STATUS
CloseSimpleTextInOnFile (
  IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *SimpleTextIn
  )
{
  EFI_STATUS  Status;
  EFI_STATUS  Status1;

  if (SimpleTextIn == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  Status = gBS->CloseEvent (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)SimpleTextIn)->SimpleTextIn.WaitForKey);

  Status1 = gBS->UninstallProtocolInterface (
                   ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)SimpleTextIn)->TheHandle,
                   &gEfiSimpleTextInProtocolGuid,
                   &(((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)SimpleTextIn)->SimpleTextIn)
                   );

  FreePool (SimpleTextIn);
  if (!EFI_ERROR (Status)) {
    return (Status1);
  } else {
    return (Status);
  }
}

/**
  Reset the text output device hardware and optionally run diagnostics.

  @param  This                pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
  @param ExtendedVerification Indicates that a more extensive test may be performed

  @retval EFI_SUCCESS         The text output device was reset.
**/
EFI_STATUS
EFIAPI
FileBasedSimpleTextOutReset (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  BOOLEAN                          ExtendedVerification
  )
{
  return (EFI_SUCCESS);
}

/**
  Verifies that all characters in a Unicode string can be output to the
  target device.

  @param[in] This     Protocol instance pointer.
  @param[in] WString  The NULL-terminated Unicode string to be examined.

  @retval EFI_SUCCESS The device(s) are capable of rendering the output string.
**/
EFI_STATUS
EFIAPI
FileBasedSimpleTextOutTestString (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  CHAR16                           *WString
  )
{
  return (EFI_SUCCESS);
}

/**
  Returns information for an available text mode that the output device(s)
  supports.

  @param[in] This               Protocol instance pointer.
  @param[in] ModeNumber         The mode number to return information on.
  @param[out] Columns           Upon return, the number of columns in the selected geometry
  @param[out] Rows              Upon return, the number of rows in the selected geometry

  @retval EFI_UNSUPPORTED       The mode number was not valid.
**/
EFI_STATUS
EFIAPI
FileBasedSimpleTextOutQueryMode (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  UINTN                            ModeNumber,
  OUT UINTN                            *Columns,
  OUT UINTN                            *Rows
  )
{
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *PassThruProtocol;

  PassThruProtocol = ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)This)->OriginalSimpleTextOut;

  // Pass the QueryMode call thru to the original SimpleTextOutProtocol
  return (PassThruProtocol->QueryMode (
                              PassThruProtocol,
                              ModeNumber,
                              Columns,
                              Rows
                              ));
}

/**
  Sets the output device(s) to a specified mode.

  @param[in] This               Protocol instance pointer.
  @param[in] ModeNumber         The mode number to set.

  @retval EFI_UNSUPPORTED       The mode number was not valid.
**/
EFI_STATUS
EFIAPI
FileBasedSimpleTextOutSetMode (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  UINTN                            ModeNumber
  )
{
  return (EFI_UNSUPPORTED);
}

/**
  Sets the background and foreground colors for the OutputString () and
  ClearScreen () functions.

  @param[in] This               Protocol instance pointer.
  @param[in] Attribute          The attribute to set. Bits 0..3 are the foreground color, and
                                bits 4..6 are the background color. All other bits are undefined
                                and must be zero. The valid Attributes are defined in this file.

  @retval EFI_SUCCESS           The attribute was set.
**/
EFI_STATUS
EFIAPI
FileBasedSimpleTextOutSetAttribute (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  UINTN                            Attribute
  )
{
  return (EFI_SUCCESS);
}

/**
  Clears the output device(s) display to the currently selected background
  color.

  @param[in] This               Protocol instance pointer.

  @retval EFI_UNSUPPORTED       The output device is not in a valid text mode.
**/
EFI_STATUS
EFIAPI
FileBasedSimpleTextOutClearScreen (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This
  )
{
  return (EFI_SUCCESS);
}

/**
  Sets the current coordinates of the cursor position

  @param[in] This               Protocol instance pointer.
  @param[in] Column             Column to put the cursor in.  Must be between zero and Column returned from QueryMode
  @param[in] Row                Row to put the cursor in.  Must be between zero and Row returned from QueryMode

  @retval EFI_SUCCESS           The operation completed successfully.
**/
EFI_STATUS
EFIAPI
FileBasedSimpleTextOutSetCursorPosition (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  UINTN                            Column,
  IN  UINTN                            Row
  )
{
  return (EFI_SUCCESS);
}

/**
  Makes the cursor visible or invisible

  @param[in] This       Protocol instance pointer.
  @param[in] Visible    If TRUE, the cursor is set to be visible. If FALSE, the cursor is
                        set to be invisible.

  @retval EFI_SUCCESS           The operation completed successfully.
**/
EFI_STATUS
EFIAPI
FileBasedSimpleTextOutEnableCursor (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  BOOLEAN                          Visible
  )
{
  return (EFI_SUCCESS);
}

/**
  Write a Unicode string to the output device.

  @param[in] This                 Protocol instance pointer.
  @param[in] WString              The NULL-terminated Unicode string to be displayed on the output
                                  device(s). All output devices must also support the Unicode
                                  drawing defined in this file.
  @retval EFI_SUCCESS             The string was output to the device.
  @retval EFI_DEVICE_ERROR        The device reported an error while attempting to output
                                  the text.
  @retval EFI_UNSUPPORTED         The output device's mode is not currently in a
                                  defined text mode.
  @retval EFI_WARN_UNKNOWN_GLYPH  This warning code indicates that some of the
                                  characters in the Unicode string could not be
                                  rendered and were skipped.
**/
EFI_STATUS
EFIAPI
FileBasedSimpleTextOutOutputString (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  CHAR16                           *WString
  )
{
  UINTN  Size;

  Size = StrLen (WString) * sizeof (CHAR16);
  return (ShellInfoObject.NewEfiShellProtocol->WriteFile (
                                                 ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)This)->FileHandle,
                                                 &Size,
                                                 WString
                                                 ));
}

/**
  Function to create a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a
  SHELL_FILE_HANDLE to support redirecting output from a file.

  @param[in]  FileHandleToUse  The pointer to the SHELL_FILE_HANDLE to use.
  @param[in]  HandleLocation   The pointer of a location to copy handle with protocol to.
  @param[in]  OriginalProtocol The pointer to the original output protocol for pass thru of functions.

  @retval NULL                There was insufficient memory available.
  @return                     A pointer to the allocated protocol structure;
**/
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *
CreateSimpleTextOutOnFile (
  IN SHELL_FILE_HANDLE                FileHandleToUse,
  IN EFI_HANDLE                       *HandleLocation,
  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *OriginalProtocol
  )
{
  SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ProtocolToReturn;
  EFI_STATUS                             Status;

  if ((HandleLocation == NULL) || (FileHandleToUse == NULL)) {
    return (NULL);
  }

  ProtocolToReturn = AllocateZeroPool (sizeof (SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL));
  if (ProtocolToReturn == NULL) {
    return (NULL);
  }

  ProtocolToReturn->FileHandle                      = FileHandleToUse;
  ProtocolToReturn->OriginalSimpleTextOut           = OriginalProtocol;
  ProtocolToReturn->SimpleTextOut.Reset             = FileBasedSimpleTextOutReset;
  ProtocolToReturn->SimpleTextOut.TestString        = FileBasedSimpleTextOutTestString;
  ProtocolToReturn->SimpleTextOut.QueryMode         = FileBasedSimpleTextOutQueryMode;
  ProtocolToReturn->SimpleTextOut.SetMode           = FileBasedSimpleTextOutSetMode;
  ProtocolToReturn->SimpleTextOut.SetAttribute      = FileBasedSimpleTextOutSetAttribute;
  ProtocolToReturn->SimpleTextOut.ClearScreen       = FileBasedSimpleTextOutClearScreen;
  ProtocolToReturn->SimpleTextOut.SetCursorPosition = FileBasedSimpleTextOutSetCursorPosition;
  ProtocolToReturn->SimpleTextOut.EnableCursor      = FileBasedSimpleTextOutEnableCursor;
  ProtocolToReturn->SimpleTextOut.OutputString      = FileBasedSimpleTextOutOutputString;
  ProtocolToReturn->SimpleTextOut.Mode              = AllocateZeroPool (sizeof (EFI_SIMPLE_TEXT_OUTPUT_MODE));
  if (ProtocolToReturn->SimpleTextOut.Mode == NULL) {
    FreePool (ProtocolToReturn);
    return (NULL);
  }

  ProtocolToReturn->SimpleTextOut.Mode->MaxMode       = OriginalProtocol->Mode->MaxMode;
  ProtocolToReturn->SimpleTextOut.Mode->Mode          = OriginalProtocol->Mode->Mode;
  ProtocolToReturn->SimpleTextOut.Mode->Attribute     = OriginalProtocol->Mode->Attribute;
  ProtocolToReturn->SimpleTextOut.Mode->CursorColumn  = OriginalProtocol->Mode->CursorColumn;
  ProtocolToReturn->SimpleTextOut.Mode->CursorRow     = OriginalProtocol->Mode->CursorRow;
  ProtocolToReturn->SimpleTextOut.Mode->CursorVisible = OriginalProtocol->Mode->CursorVisible;

  Status = gBS->InstallProtocolInterface (
                  &(ProtocolToReturn->TheHandle),
                  &gEfiSimpleTextOutProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &(ProtocolToReturn->SimpleTextOut)
                  );
  if (!EFI_ERROR (Status)) {
    *HandleLocation = ProtocolToReturn->TheHandle;
    return ((EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)ProtocolToReturn);
  } else {
    SHELL_FREE_NON_NULL (ProtocolToReturn->SimpleTextOut.Mode);
    SHELL_FREE_NON_NULL (ProtocolToReturn);
    return (NULL);
  }
}

/**
  Function to close a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a
  SHELL_FILE_HANDLE to support redirecting output from a file.

  @param[in] SimpleTextOut    The pointer to the SimpleTextOUT to close.

  @retval EFI_SUCCESS         The object was closed.
**/
EFI_STATUS
CloseSimpleTextOutOnFile (
  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *SimpleTextOut
  )
{
  EFI_STATUS  Status;

  if (SimpleTextOut == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  Status = gBS->UninstallProtocolInterface (
                  ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)SimpleTextOut)->TheHandle,
                  &gEfiSimpleTextOutProtocolGuid,
                  &(((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)SimpleTextOut)->SimpleTextOut)
                  );
  FreePool (SimpleTextOut->Mode);
  FreePool (SimpleTextOut);
  return (Status);
}
