/** @file
  Provides interface to shell console logger.

  (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2015, 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"

/**
  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
EFIAPI
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;

  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
EFIAPI
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;

  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
EFIAPI
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
EFIAPI
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
EFIAPI
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
EFIAPI
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
EFIAPI
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
EFIAPI
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
EFIAPI
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
EFIAPI
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);
}
