/** @file
  Function definitions for shell simple text in and out on top of file handles.

  Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
  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 "Shell.h"

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;

  //
  // 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);

  //
  // 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 > Size) {
    ((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile -= Size;
  } 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*
EFIAPI
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
EFIAPI
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 optionaly 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*
EFIAPI
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 {
    FreePool(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
EFIAPI
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);
  return (Status);
}
