/** @file
  Provides interface to shell console logger.

  (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2016 Hewlett-Packard Development Company, L.P.<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"

/**
  Install our intermediate ConOut into the system table to
  keep a log of all the info that is displayed to the user.

  @param[in] ScreensToSave  Sets how many screen-worths of data to save.
  @param[out] ConsoleInfo   The object to pass into later functions.

  @retval EFI_SUCCESS       The operation was successful.
  @return other             The operation failed.

  @sa ConsoleLoggerResetBuffers
  @sa InstallProtocolInterface
**/
EFI_STATUS
ConsoleLoggerInstall(
  IN CONST UINTN ScreensToSave,
  OUT CONSOLE_LOGGER_PRIVATE_DATA **ConsoleInfo
  )
{
  EFI_STATUS Status;
  ASSERT(ConsoleInfo != NULL);

  (*ConsoleInfo) = AllocateZeroPool(sizeof(CONSOLE_LOGGER_PRIVATE_DATA));
  if ((*ConsoleInfo) == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  (*ConsoleInfo)->Signature                   = CONSOLE_LOGGER_PRIVATE_DATA_SIGNATURE;
  (*ConsoleInfo)->OldConOut                   = gST->ConOut;
  (*ConsoleInfo)->OldConHandle                = gST->ConsoleOutHandle;
  (*ConsoleInfo)->Buffer                      = NULL;
  (*ConsoleInfo)->BufferSize                  = 0;
  (*ConsoleInfo)->OriginalStartRow            = 0;
  (*ConsoleInfo)->CurrentStartRow             = 0;
  (*ConsoleInfo)->RowsPerScreen               = 0;
  (*ConsoleInfo)->ColsPerScreen               = 0;
  (*ConsoleInfo)->Attributes                  = NULL;
  (*ConsoleInfo)->AttribSize                  = 0;
  (*ConsoleInfo)->ScreenCount                 = ScreensToSave;
  (*ConsoleInfo)->HistoryMode.MaxMode         = 1;
  (*ConsoleInfo)->HistoryMode.Mode            = 0;
  (*ConsoleInfo)->HistoryMode.Attribute       = 0;
  (*ConsoleInfo)->HistoryMode.CursorColumn    = 0;
  (*ConsoleInfo)->HistoryMode.CursorRow       = 0;
  (*ConsoleInfo)->HistoryMode.CursorVisible   = FALSE;
  (*ConsoleInfo)->OurConOut.Reset             = ConsoleLoggerReset;
  (*ConsoleInfo)->OurConOut.OutputString      = ConsoleLoggerOutputString;
  (*ConsoleInfo)->OurConOut.TestString        = ConsoleLoggerTestString;
  (*ConsoleInfo)->OurConOut.QueryMode         = ConsoleLoggerQueryMode;
  (*ConsoleInfo)->OurConOut.SetMode           = ConsoleLoggerSetMode;
  (*ConsoleInfo)->OurConOut.SetAttribute      = ConsoleLoggerSetAttribute;
  (*ConsoleInfo)->OurConOut.ClearScreen       = ConsoleLoggerClearScreen;
  (*ConsoleInfo)->OurConOut.SetCursorPosition = ConsoleLoggerSetCursorPosition;
  (*ConsoleInfo)->OurConOut.EnableCursor      = ConsoleLoggerEnableCursor;
  (*ConsoleInfo)->OurConOut.Mode              = gST->ConOut->Mode;
  (*ConsoleInfo)->Enabled                     = TRUE;

  Status = ConsoleLoggerResetBuffers(*ConsoleInfo);
  if (EFI_ERROR(Status)) {
    SHELL_FREE_NON_NULL((*ConsoleInfo));
    *ConsoleInfo = NULL;
    return (Status);
  }

  Status = gBS->InstallProtocolInterface(&gImageHandle, &gEfiSimpleTextOutProtocolGuid, EFI_NATIVE_INTERFACE, (VOID*)&((*ConsoleInfo)->OurConOut));
  if (EFI_ERROR(Status)) {
    SHELL_FREE_NON_NULL((*ConsoleInfo)->Buffer);
    SHELL_FREE_NON_NULL((*ConsoleInfo)->Attributes);
    SHELL_FREE_NON_NULL((*ConsoleInfo));
    *ConsoleInfo = NULL;
    return (Status);
  }

  gST->ConsoleOutHandle = gImageHandle;
  gST->ConOut           = &(*ConsoleInfo)->OurConOut;

  //
  // Update the CRC32 in the EFI System Table header
  //
  gST->Hdr.CRC32 = 0;
  gBS->CalculateCrc32 (
        (UINT8 *)&gST->Hdr,
        gST->Hdr.HeaderSize,
        &gST->Hdr.CRC32
        );
  return (Status);
}

/**
  Return the system to the state it was before InstallConsoleLogger
  was installed.

  @param[in] ConsoleInfo  The object from the install function.

  @retval EFI_SUCCESS     The operation was successful
  @return other           The operation failed.  This was from UninstallProtocolInterface.
**/
EFI_STATUS
ConsoleLoggerUninstall(
  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
  )
{
  ASSERT(ConsoleInfo != NULL);
  ASSERT(ConsoleInfo->OldConOut != NULL);

  if (ConsoleInfo->Buffer != NULL) {
    FreePool(ConsoleInfo->Buffer);
    DEBUG_CODE(ConsoleInfo->Buffer     = NULL;);
    DEBUG_CODE(ConsoleInfo->BufferSize = 0;);
  }
  if (ConsoleInfo->Attributes != NULL) {
    FreePool(ConsoleInfo->Attributes);
    DEBUG_CODE(ConsoleInfo->Attributes = NULL;);
    DEBUG_CODE(ConsoleInfo->AttribSize = 0;);
  }

  gST->ConsoleOutHandle = ConsoleInfo->OldConHandle;
  gST->ConOut = ConsoleInfo->OldConOut;

  //
  // Update the CRC32 in the EFI System Table header
  //
  gST->Hdr.CRC32 = 0;
  gBS->CalculateCrc32 (
        (UINT8 *)&gST->Hdr,
        gST->Hdr.HeaderSize,
        &gST->Hdr.CRC32
        );

  return (gBS->UninstallProtocolInterface(gImageHandle, &gEfiSimpleTextOutProtocolGuid, (VOID*)&ConsoleInfo->OurConOut));
}

/**
  Displays previously logged output back to the screen.

  This will scroll the screen forwards and backwards through the log of previous
  output.  If Rows is 0 then the size of 1/2 the screen will be scrolled.  If Rows
  is (UINTN)(-1) then the size of the screen will be scrolled.

  @param[in] Forward      If TRUE then the log will be displayed forwards (scroll to newer).
                          If FALSE then the log will be displayed backwards (scroll to older).
  @param[in] Rows         Determines how many rows the log should scroll.
  @param[in] ConsoleInfo  The pointer to the instance of the console logger information.
**/
EFI_STATUS
ConsoleLoggerDisplayHistory(
  IN CONST BOOLEAN  Forward,
  IN CONST UINTN    Rows,
  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
  )
{
  UINTN   RowChange;

  ASSERT(ConsoleInfo != NULL);

  //
  // Calculate the row number change
  //
  switch (Rows) {
  case ((UINTN)(-1)):
    RowChange = ConsoleInfo->RowsPerScreen;
    break;
  case (0):
    RowChange = ConsoleInfo->RowsPerScreen / 2;
    break;
  default:
    RowChange = Rows;
    break;
  }

  //
  // Do the math for direction
  //
  if (Forward) {
    if ((ConsoleInfo->OriginalStartRow - ConsoleInfo->CurrentStartRow) < RowChange) {
      RowChange = ConsoleInfo->OriginalStartRow - ConsoleInfo->CurrentStartRow;
    }
  } else {
    if (ConsoleInfo->CurrentStartRow < RowChange) {
      RowChange = ConsoleInfo->CurrentStartRow;
    }
  }

  //
  // If we are already at one end or the other
  //
  if (RowChange == 0) {
    return (EFI_SUCCESS);
  }

  //
  // Clear the screen
  //
  ConsoleInfo->OldConOut->ClearScreen(ConsoleInfo->OldConOut);

  //
  // Set the new start row
  //
  if (Forward) {
    ConsoleInfo->CurrentStartRow += RowChange;
  } else {
    ConsoleInfo->CurrentStartRow -= RowChange;
  }

  //
  // Change the screen
  //
  return (UpdateDisplayFromHistory(ConsoleInfo));
}

/**
  Function to return to normal output whent he scrolling is complete.
  @param[in] ConsoleInfo  The pointer to the instance of the console logger information.

  @retval EFI_SUCCESS   The operation was successful.
  @return other         The operation failed.  See UpdateDisplayFromHistory.

  @sa UpdateDisplayFromHistory
**/
EFI_STATUS
ConsoleLoggerStopHistory(
  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
  )
{
  ASSERT(ConsoleInfo != NULL);
  if (ConsoleInfo->CurrentStartRow == ConsoleInfo->OriginalStartRow) {
    return (EFI_SUCCESS);
  }

  //
  // Clear the screen
  //
  ConsoleInfo->OldConOut->ClearScreen(ConsoleInfo->OldConOut);

  ConsoleInfo->CurrentStartRow = ConsoleInfo->OriginalStartRow;
  return (UpdateDisplayFromHistory(ConsoleInfo));
}

/**
  Updates the hidden ConOut to be displaying the correct stuff.
  @param[in] ConsoleInfo  The pointer to the instance of the console logger information.

  @retval EFI_SUCCESS     The operation was successful.
  @return other           The operation failed.
**/
EFI_STATUS
UpdateDisplayFromHistory(
  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
  )
{
  EFI_STATUS      Status;
  EFI_STATUS      RetVal;
  CHAR16          *Screen;
  INT32           *Attributes;
  UINTN           CurrentRow;
  CHAR16          TempCharHolder;
  UINTN           Column;
  INT32           CurrentAttrib;
  UINTN           CurrentColumn;
  CHAR16          *StringSegment;
  CHAR16          *StringSegmentEnd;
  CHAR16          StringSegmentEndChar;
  INT32           OrigAttribute;

  ASSERT(ConsoleInfo != NULL);
  TempCharHolder = CHAR_NULL;
  RetVal = EFI_SUCCESS;
  OrigAttribute = ConsoleInfo->OldConOut->Mode->Attribute;

  //
  // Disable cursor visibility and move it to the top left corner
  //
  ConsoleInfo->OldConOut->EnableCursor       (ConsoleInfo->OldConOut, FALSE);
  ConsoleInfo->OldConOut->SetCursorPosition  (ConsoleInfo->OldConOut, 0, 0);

  Screen = &ConsoleInfo->Buffer[(ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->CurrentStartRow];
  Attributes = &ConsoleInfo->Attributes[ConsoleInfo->ColsPerScreen * ConsoleInfo->CurrentStartRow];
  for ( CurrentRow = 0
      ; CurrentRow < ConsoleInfo->RowsPerScreen
      ; CurrentRow++
      , Screen += (ConsoleInfo->ColsPerScreen + 2)
      , Attributes += ConsoleInfo->ColsPerScreen
     ){
    //
    // dont use the last char - prevents screen scroll
    //
    if (CurrentRow == (ConsoleInfo->RowsPerScreen-1)){
      TempCharHolder = Screen[ConsoleInfo->ColsPerScreen - 1];
      Screen[ConsoleInfo->ColsPerScreen - 1] = CHAR_NULL;
    }

    for ( Column = 0
        ; Column < ConsoleInfo->ColsPerScreen
        ; Column++
       ){
      if (Screen[Column] != CHAR_NULL) {
        CurrentAttrib = Attributes[Column];
        CurrentColumn = Column;
        StringSegment = &Screen[Column];

        //
        // Find the first char with a different arrribute and make that temporarily NULL
        // so we can do fewer printout statements.  (later) restore that one and we will
        // start at that collumn on the next loop.
        //
        StringSegmentEndChar = CHAR_NULL;
        for ( StringSegmentEnd = StringSegment
            ; *StringSegmentEnd != CHAR_NULL
            ; StringSegmentEnd++
            , Column++
           ){
          if (Attributes[Column] != CurrentAttrib) {
            StringSegmentEndChar = *StringSegmentEnd;
            *StringSegmentEnd    = CHAR_NULL;
            break;
          }
        } // StringSegmentEnd loop

        //
        // Now write out as much as had the same Attributes
        //

        ConsoleInfo->OldConOut->SetAttribute(ConsoleInfo->OldConOut, CurrentAttrib);
        ConsoleInfo->OldConOut->SetCursorPosition(ConsoleInfo->OldConOut, CurrentColumn, CurrentRow);
        Status = ConsoleInfo->OldConOut->OutputString(ConsoleInfo->OldConOut, StringSegment);

        if (EFI_ERROR(Status)) {
          ASSERT(FALSE);
          RetVal = Status;
        }

        //
        // If we found a change in attribute put the character back and decrement the column
        // so when it increments it will point at that character and we will start printing
        // a segment with that new attribute
        //
        if (StringSegmentEndChar != CHAR_NULL) {
          *StringSegmentEnd = StringSegmentEndChar;
          StringSegmentEndChar = CHAR_NULL;
          Column--;
        }
      }
    } // column for loop

    //
    // If we removed the last char and this was the last row put it back
    //
    if (TempCharHolder != CHAR_NULL) {
      Screen[ConsoleInfo->ColsPerScreen - 1] = TempCharHolder;
      TempCharHolder = CHAR_NULL;
    }
  } // row for loop

  //
  // If we are setting the screen back to original turn on the cursor and make it visible
  // and set the attributes back to what they were
  //
  if (ConsoleInfo->CurrentStartRow == ConsoleInfo->OriginalStartRow) {
    ConsoleInfo->OldConOut->SetAttribute (
                                ConsoleInfo->OldConOut,
                                ConsoleInfo->HistoryMode.Attribute
                               );
    ConsoleInfo->OldConOut->SetCursorPosition (
                                ConsoleInfo->OldConOut,
                                ConsoleInfo->HistoryMode.CursorColumn,
                                ConsoleInfo->HistoryMode.CursorRow - ConsoleInfo->OriginalStartRow
                               );

    Status = ConsoleInfo->OldConOut->EnableCursor (
                                ConsoleInfo->OldConOut,
                                ConsoleInfo->HistoryMode.CursorVisible
                               );
    if (EFI_ERROR (Status)) {
      RetVal = Status;
    }
  } else {
    ConsoleInfo->OldConOut->SetAttribute (
                                ConsoleInfo->OldConOut,
                                OrigAttribute
                               );
  }

  return (RetVal);
}

/**
  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.
  @retval EFI_DEVICE_ERROR    The text output device is not functioning correctly and
                              could not be reset.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerReset (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  IN  BOOLEAN                         ExtendedVerification
  )
{
  EFI_STATUS                  Status;
  CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
  ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);

  //
  // Forward the request to the original ConOut
  //
  Status = ConsoleInfo->OldConOut->Reset (ConsoleInfo->OldConOut, ExtendedVerification);

  //
  // Check that the buffers are still correct for logging
  //
  if (!EFI_ERROR (Status)) {
    ConsoleLoggerResetBuffers(ConsoleInfo);
    if (ExtendedVerification) {
      ConsoleInfo->OriginalStartRow = 0;
      ConsoleInfo->CurrentStartRow = 0;
    }
  }

  return Status;
}

/**
  Appends a string to the history buffer.  If the buffer is full then the oldest
  information in the buffer will be dropped.  Information is added in a line by
  line manner such that an empty line takes up just as much space as a full line.

  @param[in] String       String pointer to add.
  @param[in] ConsoleInfo  The pointer to the instance of the console logger information.
**/
EFI_STATUS
AppendStringToHistory(
  IN CONST CHAR16 *String,
  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
  )
{
  CONST CHAR16  *Walker;
  UINTN         CopySize;
  UINTN         PrintIndex;
  UINTN         Index;

  ASSERT(ConsoleInfo != NULL);

  for ( Walker = String
      ; Walker != NULL && *Walker != CHAR_NULL
      ; Walker++
     ){
    switch (*Walker) {
    case (CHAR_BACKSPACE):
      if (ConsoleInfo->HistoryMode.CursorColumn > 0) {
        ConsoleInfo->HistoryMode.CursorColumn--;
      }
      break;
    case (CHAR_LINEFEED):
      if (ConsoleInfo->HistoryMode.CursorRow >= (INT32)((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)-1)) {
        //
        // Should never be bigger
        //
        ASSERT(ConsoleInfo->HistoryMode.CursorRow == (INT32)((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)-1));

        //
        // scroll history attributes 'up' 1 row and set the last row to default attribute
        //
        CopySize = ConsoleInfo->ColsPerScreen
                 * ((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount) - 1)
                 * sizeof(ConsoleInfo->Attributes[0]);
        ASSERT(CopySize < ConsoleInfo->AttribSize);
        CopyMem(
          ConsoleInfo->Attributes,
          ConsoleInfo->Attributes + ConsoleInfo->ColsPerScreen,
          CopySize
         );

        for ( Index = 0
            ; Index < ConsoleInfo->ColsPerScreen
            ; Index++
           ){
          *(ConsoleInfo->Attributes + (CopySize/sizeof(ConsoleInfo->Attributes[0])) + Index) = ConsoleInfo->HistoryMode.Attribute;
        }

        //
        // scroll history buffer 'up' 1 row and set the last row to spaces (L' ')
        //
        CopySize = (ConsoleInfo->ColsPerScreen + 2)
                 * ((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount) - 1)
                 * sizeof(ConsoleInfo->Buffer[0]);
        ASSERT(CopySize < ConsoleInfo->BufferSize);
        CopyMem(
          ConsoleInfo->Buffer,
          ConsoleInfo->Buffer + (ConsoleInfo->ColsPerScreen + 2),
          CopySize
         );

        //
        // Set that last row of chars to spaces
        //
        SetMem16(((UINT8*)ConsoleInfo->Buffer)+CopySize, ConsoleInfo->ColsPerScreen*sizeof(CHAR16), L' ');
      } else {
        //
        // we are not on the last row
        //

        //
        // We should not be scrolling history
        //
        ASSERT (ConsoleInfo->OriginalStartRow == ConsoleInfo->CurrentStartRow);
        //
        // are we at the end of a row?
        //
        if (ConsoleInfo->HistoryMode.CursorRow == (INT32) (ConsoleInfo->OriginalStartRow + ConsoleInfo->RowsPerScreen - 1)) {
          ConsoleInfo->OriginalStartRow++;
          ConsoleInfo->CurrentStartRow++;
        }
        ConsoleInfo->HistoryMode.CursorRow++;
      }
      break;
    case (CHAR_CARRIAGE_RETURN):
      //
      // Move the cursor to the beginning of the current row.
      //
      ConsoleInfo->HistoryMode.CursorColumn = 0;
      break;
    default:
      //
      // Acrtually print characters into the history buffer
      //

      PrintIndex = ConsoleInfo->HistoryMode.CursorRow * ConsoleInfo->ColsPerScreen + ConsoleInfo->HistoryMode.CursorColumn;

      for ( // no initializer needed
          ; ConsoleInfo->HistoryMode.CursorColumn < (INT32) ConsoleInfo->ColsPerScreen
          ; ConsoleInfo->HistoryMode.CursorColumn++
          , PrintIndex++
          , Walker++
         ){
        if (*Walker == CHAR_NULL
          ||*Walker == CHAR_BACKSPACE
          ||*Walker == CHAR_LINEFEED
          ||*Walker == CHAR_CARRIAGE_RETURN
         ){
            Walker--;
            break;
        }
        //
        // The buffer is 2*CursorRow more since it has that many \r\n characters at the end of each row.
        //

        ASSERT(PrintIndex + ConsoleInfo->HistoryMode.CursorRow < ConsoleInfo->BufferSize);
        ConsoleInfo->Buffer[PrintIndex + (2*ConsoleInfo->HistoryMode.CursorRow)] = *Walker;
        ASSERT(PrintIndex < ConsoleInfo->AttribSize);
        ConsoleInfo->Attributes[PrintIndex] = ConsoleInfo->HistoryMode.Attribute;
      } // for loop

      //
      // Add the carriage return and line feed at the end of the lines
      //
      if (ConsoleInfo->HistoryMode.CursorColumn >= (INT32)ConsoleInfo->ColsPerScreen) {
        AppendStringToHistory(L"\r\n", ConsoleInfo);
        Walker--;
      }

      break;
    } // switch for character
  } // for loop

  return (EFI_SUCCESS);
}

/**
  Worker function to handle printing the output to the screen
  and the history buffer

  @param[in] String               The string to output
  @param[in] ConsoleInfo          The pointer to the instance of the console logger information.

  @retval EFI_SUCCESS             The string was printed
  @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
ConsoleLoggerOutputStringSplit(
  IN CONST CHAR16   *String,
  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
  )
{
  EFI_STATUS    Status;

  //
  // Forward the request to the original ConOut
  //
  Status = ConsoleInfo->OldConOut->OutputString (ConsoleInfo->OldConOut, (CHAR16*)String);

  if (EFI_ERROR(Status)) {
    return (Status);
  }

  return (AppendStringToHistory(String, ConsoleInfo));
}

/**
  Function to handle page break mode.

  This function will prompt for continue or break.

  @retval EFI_SUCCESS   Continue was choosen
  @return other         Break was choosen
**/
EFI_STATUS
ConsoleLoggerDoPageBreak(
  VOID
  )
{
  SHELL_PROMPT_RESPONSE *Resp;
  EFI_STATUS            Status;

  Resp = NULL;
  ASSERT(ShellInfoObject.PageBreakEnabled);
  ShellInfoObject.PageBreakEnabled = FALSE;
  Status = ShellPromptForResponseHii(ShellPromptResponseTypeQuitContinue, STRING_TOKEN(STR_SHELL_QUIT_CONT), ShellInfoObject.HiiHandle, (VOID**)&Resp);
  ShellInfoObject.PageBreakEnabled = TRUE;
  ASSERT(Resp != NULL);
  if (Resp == NULL) {
    return (EFI_NOT_FOUND);
  }
  if (EFI_ERROR(Status)) {
    if (Resp != NULL) {
      FreePool(Resp);
    }
    return (Status);
  }
  if (*Resp == ShellPromptResponseContinue) {
    FreePool(Resp);
    ShellInfoObject.ConsoleInfo->RowCounter                   = 0;
//    ShellInfoObject.ConsoleInfo->OurConOut.Mode->CursorRow    = 0;
//    ShellInfoObject.ConsoleInfo->OurConOut.Mode->CursorColumn = 0;

    return (EFI_SUCCESS);
  } else if (*Resp == ShellPromptResponseQuit) {
    FreePool(Resp);
    ShellInfoObject.ConsoleInfo->Enabled = FALSE;
    //
    // When user wants to quit, the shell should stop running the command.
    //
    gBS->SignalEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak);
    return (EFI_DEVICE_ERROR);
  } else {
    ASSERT(FALSE);
  }
  return (EFI_SUCCESS);
}
/**
  Worker function to handle printing the output with page breaks.

  @param[in] String               The string to output
  @param[in] ConsoleInfo          The pointer to the instance of the console logger information.

  @retval EFI_SUCCESS             The string was printed
  @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
ConsoleLoggerPrintWithPageBreak(
  IN CONST CHAR16   *String,
  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
  )
{
  CONST CHAR16  *Walker;
  CONST CHAR16  *LineStart;
  CHAR16        *StringCopy;
  CHAR16        TempChar;

  StringCopy = NULL;
  StringCopy = StrnCatGrow(&StringCopy, NULL, String, 0);
  if (StringCopy == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  for ( Walker = StringCopy
      , LineStart = StringCopy
      ; Walker != NULL && *Walker != CHAR_NULL
      ; Walker++
     ){
    switch (*Walker) {
    case (CHAR_BACKSPACE):
      if (ConsoleInfo->OurConOut.Mode->CursorColumn > 0) {
        ConsoleInfo->OurConOut.Mode->CursorColumn--;
      }
      break;
    case (CHAR_LINEFEED):
      //
      // add a temp NULL terminator
      //
      TempChar = *(Walker + 1);
      *((CHAR16*)(Walker+1)) = CHAR_NULL;

      //
      // output the string
      //
      ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);

      //
      // restore the temp NULL terminator to it's original character
      //
      *((CHAR16*)(Walker+1)) = TempChar;

      //
      // Update LineStart Variable
      //
      LineStart = Walker + 1;

      //
      // increment row count
      //
      ShellInfoObject.ConsoleInfo->RowCounter++;
      ConsoleInfo->OurConOut.Mode->CursorRow++;

      break;
    case (CHAR_CARRIAGE_RETURN):
      //
      // Move the cursor to the beginning of the current row.
      //
      ConsoleInfo->OurConOut.Mode->CursorColumn = 0;
      break;
    default:
      //
      // increment column count
      //
      ConsoleInfo->OurConOut.Mode->CursorColumn++;
      //
      // check if that is the last column
      //
      if ((INTN)ConsoleInfo->ColsPerScreen == ConsoleInfo->OurConOut.Mode->CursorColumn + 1) {
        //
        // output a line similar to the linefeed character.
        //

        //
        // add a temp NULL terminator
        //
        TempChar = *(Walker + 1);
        *((CHAR16*)(Walker+1)) = CHAR_NULL;

        //
        // output the string
        //
        ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);

        //
        // restore the temp NULL terminator to it's original character
        //
        *((CHAR16*)(Walker+1)) = TempChar;

        //
        // Update LineStart Variable
        //
        LineStart = Walker + 1;

        //
        // increment row count and zero the column
        //
        ShellInfoObject.ConsoleInfo->RowCounter++;
        ConsoleInfo->OurConOut.Mode->CursorRow++;
        ConsoleInfo->OurConOut.Mode->CursorColumn = 0;
      } // last column on line
      break;
    } // switch for character

    //
    // check if that was the last printable row.  If yes handle PageBreak mode
    //
    if ((ConsoleInfo->RowsPerScreen) -1 == ShellInfoObject.ConsoleInfo->RowCounter) {
      if (EFI_ERROR(ConsoleLoggerDoPageBreak())) {
        //
        // We got an error which means 'break' and halt the printing
        //
        SHELL_FREE_NON_NULL(StringCopy);
        return (EFI_DEVICE_ERROR);
      }
    }
  } // for loop

  if (LineStart != NULL && *LineStart != CHAR_NULL) {
    ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);
  }

  SHELL_FREE_NON_NULL(StringCopy);
  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
ConsoleLoggerOutputString (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  IN  CHAR16                          *WString
  )
{
  EFI_STATUS                        Status;
  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TxtInEx;
  EFI_KEY_DATA                      KeyData;
  UINTN                             EventIndex;
  CONSOLE_LOGGER_PRIVATE_DATA       *ConsoleInfo;

  ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);
  if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
    return (EFI_UNSUPPORTED);
  }
  ASSERT(ShellInfoObject.ConsoleInfo == ConsoleInfo);

  Status = gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **) &TxtInEx);
  if (!EFI_ERROR (Status)) {
    while (ShellInfoObject.HaltOutput) {

      ShellInfoObject.HaltOutput = FALSE;
      //
      // just get some key
      //
      Status = gBS->WaitForEvent (1, &TxtInEx->WaitForKeyEx, &EventIndex);
      ASSERT_EFI_ERROR (Status);
      Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
      if (EFI_ERROR(Status)) {
        break;
      }

      if ((KeyData.Key.UnicodeChar == L's') && (KeyData.Key.ScanCode == SCAN_NULL) &&
          ((KeyData.KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED)) ||
           (KeyData.KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID | EFI_RIGHT_CONTROL_PRESSED))
          )
         ) {
        ShellInfoObject.HaltOutput = TRUE;
      }
    }
  }

  if (!ShellInfoObject.ConsoleInfo->Enabled) {
    return (EFI_DEVICE_ERROR);
  } else if (ShellInfoObject.PageBreakEnabled) {
    return (ConsoleLoggerPrintWithPageBreak(WString, ConsoleInfo));
  } else {
    return (ConsoleLoggerOutputStringSplit(WString, ConsoleInfo));
  }
}

/**
  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 for the output
                      device(s).

  @retval EFI_SUCCESS           The device(s) are capable of rendering the output string.
  @retval EFI_UNSUPPORTED       Some of the characters in the Unicode string cannot be
                                rendered by one or more of the output devices mapped
                                by the EFI handle.

**/
EFI_STATUS
EFIAPI
ConsoleLoggerTestString (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  CHAR16                        *WString
  )
{
  CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
  ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);
  //
  // Forward the request to the original ConOut
  //
  return (ConsoleInfo->OldConOut->TestString (ConsoleInfo->OldConOut, WString));
}

/**
  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_SUCCESS           The requested mode information was returned.
  @retval EFI_DEVICE_ERROR      The device had an error and could not
                                complete the request.
  @retval EFI_UNSUPPORTED       The mode number was not valid.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerQueryMode (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  UINTN                         ModeNumber,
  OUT UINTN                         *Columns,
  OUT UINTN                         *Rows
  )
{
  CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
  ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);
  //
  // Forward the request to the original ConOut
  //
  return (ConsoleInfo->OldConOut->QueryMode (
    ConsoleInfo->OldConOut,
    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_SUCCESS           The requested text mode was set.
  @retval EFI_DEVICE_ERROR      The device had an error and
                                could not complete the request.
  @retval EFI_UNSUPPORTED       The mode number was not valid.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerSetMode (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *This,
  IN  UINTN                             ModeNumber
  )
{
  EFI_STATUS                  Status;

  CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
  ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);

  //
  // Forward the request to the original ConOut
  //
  Status = ConsoleInfo->OldConOut->SetMode (ConsoleInfo->OldConOut, ModeNumber);

  //
  // Check that the buffers are still correct for logging
  //
  if (!EFI_ERROR (Status)) {
    ConsoleInfo->OurConOut.Mode = ConsoleInfo->OldConOut->Mode;
    ConsoleLoggerResetBuffers(ConsoleInfo);
    ConsoleInfo->OriginalStartRow = 0;
    ConsoleInfo->CurrentStartRow = 0;
    ConsoleInfo->OurConOut.ClearScreen (&ConsoleInfo->OurConOut);
  }

  return Status;
}

/**
  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.
  @retval EFI_DEVICE_ERROR      The device had an error and
                                could not complete the request.
  @retval EFI_UNSUPPORTED       The attribute requested is not defined.

**/
EFI_STATUS
EFIAPI
ConsoleLoggerSetAttribute (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  IN  UINTN                           Attribute
  )
{
  EFI_STATUS                  Status;

  CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
  ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);

  //
  // Forward the request to the original ConOut
  //
  Status = ConsoleInfo->OldConOut->SetAttribute (ConsoleInfo->OldConOut, Attribute);

  //
  // Record console output history
  //
  if (!EFI_ERROR (Status)) {
    ConsoleInfo->HistoryMode.Attribute = (INT32) Attribute;
  }

  return Status;
}

/**
  Clears the output device(s) display to the currently selected background
  color.

  @param[in] This               Protocol instance pointer.

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval EFI_DEVICE_ERROR      The device had an error and
                                could not complete the request.
  @retval EFI_UNSUPPORTED       The output device is not in a valid text mode.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerClearScreen (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This
  )
{
  EFI_STATUS        Status;
  CHAR16            *Screen;
  INT32             *Attributes;
  UINTN             Row;
  UINTN             Column;
  CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;

  if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
    return (EFI_UNSUPPORTED);
  }

  ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);

  //
  // Forward the request to the original ConOut
  //
  Status = ConsoleInfo->OldConOut->ClearScreen (ConsoleInfo->OldConOut);

  //
  // Record console output history
  //
  if (!EFI_ERROR (Status)) {
    Screen = &ConsoleInfo->Buffer[(ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->CurrentStartRow];
    Attributes = &ConsoleInfo->Attributes[ConsoleInfo->ColsPerScreen * ConsoleInfo->CurrentStartRow];
    for ( Row = ConsoleInfo->OriginalStartRow
        ; Row < (ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)
        ; Row++
       ){
      for ( Column = 0
          ; Column < ConsoleInfo->ColsPerScreen
          ; Column++
          , Screen++
          , Attributes++
         ){
        *Screen = L' ';
        *Attributes = ConsoleInfo->OldConOut->Mode->Attribute;
      }
      //
      // Skip the NULL on each column end in text buffer only
      //
      Screen += 2;
    }
    ConsoleInfo->HistoryMode.CursorColumn = 0;
    ConsoleInfo->HistoryMode.CursorRow    = 0;
  }

  return Status;
}

/**
  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.
  @retval EFI_DEVICE_ERROR      The device had an error and
                                could not complete the request.
  @retval EFI_UNSUPPORTED       The output device is not in a valid text mode, or the
                                cursor position is invalid for the current mode.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerSetCursorPosition (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  UINTN                         Column,
  IN  UINTN                         Row
  )
{
  EFI_STATUS                  Status;
  CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;

  if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
    return (EFI_UNSUPPORTED);
  }

  ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);
  //
  // Forward the request to the original ConOut
  //
  Status = ConsoleInfo->OldConOut->SetCursorPosition (
    ConsoleInfo->OldConOut,
    Column,
    Row
   );

  //
  // Record console output history
  //
  if (!EFI_ERROR (Status)) {
    ConsoleInfo->HistoryMode.CursorColumn = (INT32)Column;
    ConsoleInfo->HistoryMode.CursorRow    = (INT32)(ConsoleInfo->OriginalStartRow + Row);
  }

  return Status;
}

/**
  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.
  @retval EFI_DEVICE_ERROR      The device had an error and could not complete the
                                request, or the device does not support changing
                                the cursor mode.
  @retval EFI_UNSUPPORTED       The output device is not in a valid text mode.
**/
EFI_STATUS
EFIAPI
ConsoleLoggerEnableCursor (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  BOOLEAN                       Visible
  )
{
  EFI_STATUS                  Status;

  CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
  ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);
  //
  // Forward the request to the original ConOut
  //
  Status = ConsoleInfo->OldConOut->EnableCursor (ConsoleInfo->OldConOut, Visible);

  //
  // Record console output history
  //
  if (!EFI_ERROR (Status)) {
    ConsoleInfo->HistoryMode.CursorVisible = Visible;
  }

  return Status;
}

/**
  Function to update and verify that the current buffers are correct.

  @param[in] ConsoleInfo  The pointer to the instance of the console logger information.

  This will be used when a mode has changed or a reset ocurred to verify all
  history buffers.
**/
EFI_STATUS
ConsoleLoggerResetBuffers(
  IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
  )
{
  EFI_STATUS Status;

  if (ConsoleInfo->Buffer != NULL) {
    FreePool(ConsoleInfo->Buffer);
    ConsoleInfo->Buffer     = NULL;
    ConsoleInfo->BufferSize = 0;
  }
  if (ConsoleInfo->Attributes != NULL) {
    FreePool(ConsoleInfo->Attributes);
    ConsoleInfo->Attributes = NULL;
    ConsoleInfo->AttribSize = 0;
  }

  Status = gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &ConsoleInfo->ColsPerScreen, &ConsoleInfo->RowsPerScreen);
  if (EFI_ERROR(Status)){
    return (Status);
  }

  ConsoleInfo->BufferSize = (ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount * sizeof(ConsoleInfo->Buffer[0]);
  ConsoleInfo->AttribSize = ConsoleInfo->ColsPerScreen * ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount * sizeof(ConsoleInfo->Attributes[0]);

  ConsoleInfo->Buffer = (CHAR16*)AllocateZeroPool(ConsoleInfo->BufferSize);

  if (ConsoleInfo->Buffer == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  ConsoleInfo->Attributes = (INT32*)AllocateZeroPool(ConsoleInfo->AttribSize);
  if (ConsoleInfo->Attributes == NULL) {
    FreePool(ConsoleInfo->Buffer);
    ConsoleInfo->Buffer     = NULL;
    return (EFI_OUT_OF_RESOURCES);
  }

  CopyMem (&ConsoleInfo->HistoryMode, ConsoleInfo->OldConOut->Mode, sizeof (EFI_SIMPLE_TEXT_OUTPUT_MODE));

  return (EFI_SUCCESS);
}
