/** @file

Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent


**/

#include "Edb.h"

/**
  Set the current coordinates of the cursor position.

  @param  ConOut        Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
  @param  Column        The position to set the cursor to.
  @param  Row           The position to set the cursor to.
  @param  LineLength    Length of a line.
  @param  TotalRow      Total row of a screen.
  @param  Str           Point to the string.
  @param  StrPos        The position of the string.
  @param  Len           The length of the string.

**/
VOID
EFIAPI
SetCursorPosition (
  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut,
  IN  UINTN                           Column,
  IN  INTN                            Row,
  IN  UINTN                           LineLength,
  IN  UINTN                           TotalRow,
  IN  CHAR16                          *Str,
  IN  UINTN                           StrPos,
  IN  UINTN                           Len
  );

/**

  Function waits for a given event to fire, or for an optional timeout to expire.

  @param  Event            - The event to wait for
  @param  Timeout          - An optional timeout value in 100 ns units.

  @retval EFI_SUCCESS       - Event fired before Timeout expired.
  @retval EFI_TIME_OUT     - Timout expired before Event fired..

**/
EFI_STATUS
EFIAPI
WaitForSingleEvent (
  IN EFI_EVENT  Event,
  IN UINT64     Timeout OPTIONAL
  )
{
  EFI_STATUS  Status;
  UINTN       Index;
  EFI_EVENT   TimerEvent;
  EFI_EVENT   WaitList[2];

  if (Timeout != 0) {
    //
    // Create a timer event
    //
    Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
    if (!EFI_ERROR (Status)) {
      //
      // Set the timer event
      //
      gBS->SetTimer (
             TimerEvent,
             TimerRelative,
             Timeout
             );

      //
      // Wait for the original event or the timer
      //
      WaitList[0] = Event;
      WaitList[1] = TimerEvent;
      Status      = gBS->WaitForEvent (2, WaitList, &Index);
      gBS->CloseEvent (TimerEvent);

      //
      // If the timer expired, change the return to timed out
      //
      if (!EFI_ERROR (Status) && (Index == 1)) {
        Status = EFI_TIMEOUT;
      }
    }
  } else {
    //
    // No timeout... just wait on the event
    //
    Status = gBS->WaitForEvent (1, &Event, &Index);
    ASSERT (!EFI_ERROR (Status));
    ASSERT (Index == 0);
  }

  return Status;
}

/**

  Move the cursor position one character backward.

  @param  LineLength       Length of a line. Get it by calling QueryMode
  @param  Column           Current column of the cursor position
  @param  Row              Current row of the cursor position

**/
VOID
EFIAPI
ConMoveCursorBackward (
  IN     UINTN  LineLength,
  IN OUT UINTN  *Column,
  IN OUT UINTN  *Row
  )
{
  ASSERT (Column != NULL);
  ASSERT (Row != NULL);
  //
  // If current column is 0, move to the last column of the previous line,
  // otherwise, just decrement column.
  //
  if (*Column == 0) {
    (*Column) = LineLength - 1;
    //
    //   if (*Row > 0) {
    //
    (*Row)--;
    //
    // }
    //
  } else {
    (*Column)--;
  }
}

/**

  Move the cursor position one character backward.

  @param  LineLength       Length of a line. Get it by calling QueryMode
  @param  TotalRow         Total row of a screen, get by calling QueryMode
  @param  Column           Current column of the cursor position
  @param  Row              Current row of the cursor position

**/
VOID
EFIAPI
ConMoveCursorForward (
  IN     UINTN  LineLength,
  IN     UINTN  TotalRow,
  IN OUT UINTN  *Column,
  IN OUT UINTN  *Row
  )
{
  ASSERT (Column != NULL);
  ASSERT (Row != NULL);
  //
  // If current column is at line end, move to the first column of the nest
  // line, otherwise, just increment column.
  //
  (*Column)++;
  if (*Column >= LineLength) {
    (*Column) = 0;
    if ((*Row) < TotalRow - 1) {
      (*Row)++;
    }
  }
}

CHAR16  mBackupSpace[EFI_DEBUG_INPUS_BUFFER_SIZE];
CHAR16  mInputBufferHistory[EFI_DEBUG_INPUS_BUFFER_SIZE];

/**

  Get user input.

  @param  Prompt       The prompt string.
  @param  InStr        Point to the input string.
  @param  StrLength    The max length of string user can input.

**/
VOID
EFIAPI
Input (
  IN CHAR16   *Prompt OPTIONAL,
  OUT CHAR16  *InStr,
  IN UINTN    StrLength
  )
{
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut;
  EFI_SIMPLE_TEXT_INPUT_PROTOCOL   *ConIn;
  BOOLEAN                          Done;
  UINTN                            Column;
  UINTN                            Row;
  UINTN                            StartColumn;
  UINTN                            Update;
  UINTN                            Delete;
  UINTN                            Len;
  UINTN                            StrPos;
  UINTN                            Index;
  UINTN                            LineLength;
  UINTN                            TotalRow;
  UINTN                            SkipLength;
  UINTN                            OutputLength;
  UINTN                            TailRow;
  UINTN                            TailColumn;
  EFI_INPUT_KEY                    Key;
  BOOLEAN                          InsertMode;
  BOOLEAN                          NeedAdjust;
  UINTN                            SubIndex;
  CHAR16                           *CommandStr;

  ConOut = gST->ConOut;
  ConIn  = gST->ConIn;

  ASSERT (ConOut != NULL);
  ASSERT (ConIn != NULL);
  ASSERT (InStr != NULL);

  if (Prompt != NULL) {
    ConOut->OutputString (ConOut, Prompt);
  }

  //
  // Read a line from the console
  //
  Len          = 0;
  StrPos       = 0;
  OutputLength = 0;
  Update       = 0;
  Delete       = 0;
  InsertMode   = TRUE;
  NeedAdjust   = FALSE;

  //
  // If buffer is not large enough to hold a CHAR16, do nothing.
  //
  if (StrLength < 1) {
    return;
  }

  //
  // Get the screen setting and the current cursor location
  //
  StartColumn = ConOut->Mode->CursorColumn;
  Column      = StartColumn;
  Row         = ConOut->Mode->CursorRow;
  ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &LineLength, &TotalRow);
  if (LineLength == 0) {
    return;
  }

  SetMem (InStr, StrLength * sizeof (CHAR16), 0);
  Done = FALSE;
  do {
    //
    // Read a key
    //
    WaitForSingleEvent (ConIn->WaitForKey, 0);
    ConIn->ReadKeyStroke (ConIn, &Key);

    switch (Key.UnicodeChar) {
      case CHAR_CARRIAGE_RETURN:
        //
        // All done, print a newline at the end of the string
        //
        TailRow    = Row + (Len - StrPos + Column) / LineLength;
        TailColumn = (Len - StrPos + Column) % LineLength;
        Done       = TRUE;
        break;

      case CHAR_BACKSPACE:
        if (StrPos != 0) {
          //
          // If not move back beyond string beginning, move all characters behind
          // the current position one character forward
          //
          StrPos -= 1;
          Update  = StrPos;
          Delete  = 1;
          CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos));

          //
          // Adjust the current column and row
          //
          ConMoveCursorBackward (LineLength, &Column, &Row);

          NeedAdjust = TRUE;
        }

        break;

      default:
        if (Key.UnicodeChar >= ' ') {
          //
          // If we are at the buffer's end, drop the key
          //
          if ((Len == StrLength - 1) && (InsertMode || (StrPos == Len))) {
            break;
          }

          //
          // If in insert mode, move all characters behind the current position
          // one character backward to make space for this character. Then store
          // the character.
          //
          if (InsertMode) {
            for (Index = Len; Index > StrPos; Index -= 1) {
              InStr[Index] = InStr[Index - 1];
            }
          }

          InStr[StrPos] = Key.UnicodeChar;
          Update        = StrPos;

          StrPos      += 1;
          OutputLength = 1;
        }

        break;

      case 0:
        switch (Key.ScanCode) {
          case SCAN_DELETE:
            //
            // Move characters behind current position one character forward
            //
            if (Len != 0) {
              Update = StrPos;
              Delete = 1;
              CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos));

              NeedAdjust = TRUE;
            }

            break;

          case SCAN_LEFT:
            //
            // Adjust current cursor position
            //
            if (StrPos != 0) {
              StrPos -= 1;
              ConMoveCursorBackward (LineLength, &Column, &Row);
            }

            break;

          case SCAN_RIGHT:
            //
            // Adjust current cursor position
            //
            if (StrPos < Len) {
              StrPos += 1;
              ConMoveCursorForward (LineLength, TotalRow, &Column, &Row);
            }

            break;

          case SCAN_HOME:
            //
            // Move current cursor position to the beginning of the command line
            //
            Row   -= (StrPos + StartColumn) / LineLength;
            Column = StartColumn;
            StrPos = 0;
            break;

          case SCAN_END:
            //
            // Move current cursor position to the end of the command line
            //
            TailRow    = Row + (Len - StrPos + Column) / LineLength;
            TailColumn = (Len - StrPos + Column) % LineLength;
            Row        = TailRow;
            Column     = TailColumn;
            StrPos     = Len;
            break;

          case SCAN_ESC:
            //
            // Prepare to clear the current command line
            //
            InStr[0]     = 0;
            Update       = 0;
            Delete       = Len;
            Row         -= (StrPos + StartColumn) / LineLength;
            Column       = StartColumn;
            OutputLength = 0;

            NeedAdjust = TRUE;
            break;

          case SCAN_INSERT:
            //
            // Toggle the SEnvInsertMode flag
            //
            InsertMode = (BOOLEAN) !InsertMode;
            break;

          case SCAN_UP:
          case SCAN_DOWN:
            //
            // show history
            //
            CopyMem (InStr, mInputBufferHistory, StrLength * sizeof (CHAR16));
            StrPos       = StrLen (mInputBufferHistory);
            Update       = 0;
            Delete       = 0;
            OutputLength = 0;

            TailRow    = Row + (StrPos + StartColumn) / LineLength;
            TailColumn = (StrPos + StartColumn) % LineLength;
            Row        = TailRow;
            Column     = TailColumn;
            NeedAdjust = FALSE;

            ConOut->SetCursorPosition (ConOut, StartColumn, Row);
            for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) {
              mBackupSpace[SubIndex] = L' ';
            }

            EDBPrint (mBackupSpace);
            SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN)) * sizeof (CHAR16), 0);

            ConOut->SetCursorPosition (ConOut, StartColumn, Row);
            Len = StrPos;

            break;

          case SCAN_F1:
          case SCAN_F2:
          case SCAN_F3:
          case SCAN_F4:
          case SCAN_F5:
          case SCAN_F6:
          case SCAN_F7:
          case SCAN_F8:
          case SCAN_F9:
          case SCAN_F10:
          case SCAN_F11:
          case SCAN_F12:
            CommandStr = GetCommandNameByKey (Key);
            if (CommandStr != NULL) {
              StrnCpyS (InStr, StrLength, CommandStr, StrLength - 1);
              return;
            }

            break;
        }
    }

    if (Done) {
      break;
    }

    //
    // If we need to update the output do so now
    //
    if (Update != -1) {
      if (NeedAdjust) {
        ConOut->SetCursorPosition (ConOut, Column, Row);
        for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) {
          mBackupSpace[SubIndex] = L' ';
        }

        EDBPrint (mBackupSpace);
        SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN)) * sizeof (CHAR16), 0);
        ConOut->SetCursorPosition (ConOut, Column, Row);
        NeedAdjust = FALSE;
      }

      EDBPrint (InStr + Update);
      Len = StrLen (InStr);

      if (Delete != 0) {
        SetMem (InStr + Len, Delete * sizeof (CHAR16), 0x00);
      }

      if (StrPos > Len) {
        StrPos = Len;
      }

      Update = (UINTN)-1;

      //
      // After using print to reflect newly updates, if we're not using
      // BACKSPACE and DELETE, we need to move the cursor position forward,
      // so adjust row and column here.
      //
      if ((Key.UnicodeChar != CHAR_BACKSPACE) && !((Key.UnicodeChar == 0) && (Key.ScanCode == SCAN_DELETE))) {
        //
        // Calulate row and column of the tail of current string
        //
        TailRow    = Row + (Len - StrPos + Column + OutputLength) / LineLength;
        TailColumn = (Len - StrPos + Column + OutputLength) % LineLength;

        //
        // If the tail of string reaches screen end, screen rolls up, so if
        // Row does not equal TailRow, Row should be decremented
        //
        // (if we are recalling commands using UPPER and DOWN key, and if the
        // old command is too long to fit the screen, TailColumn must be 79.
        //
        if ((TailColumn == 0) && (TailRow >= TotalRow) && ((UINTN)Row != TailRow)) {
          Row--;
        }

        //
        // Calculate the cursor position after current operation. If cursor
        // reaches line end, update both row and column, otherwise, only
        // column will be changed.
        //
        if (Column + OutputLength >= LineLength) {
          SkipLength = OutputLength - (LineLength - Column);

          Row += SkipLength / LineLength + 1;
          if ((UINTN)Row > TotalRow - 1) {
            Row = TotalRow - 1;
          }

          Column = SkipLength % LineLength;
        } else {
          Column += OutputLength;
        }
      }

      Delete = 0;
    }

    //
    // Set the cursor position for this key
    //
    SetCursorPosition (ConOut, Column, Row, LineLength, TotalRow, InStr, StrPos, Len);
  } while (!Done);

  CopyMem (mInputBufferHistory, InStr, StrLength * sizeof (CHAR16));

  //
  // Return the data to the caller
  //
  return;
}

/**
  Set the current coordinates of the cursor position.

  @param  ConOut        Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
  @param  Column        The position to set the cursor to.
  @param  Row           The position to set the cursor to.
  @param  LineLength    Length of a line.
  @param  TotalRow      Total row of a screen.
  @param  Str           Point to the string.
  @param  StrPos        The position of the string.
  @param  Len           The length of the string.

**/
VOID
EFIAPI
SetCursorPosition (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut,
  IN  UINTN                            Column,
  IN  INTN                             Row,
  IN  UINTN                            LineLength,
  IN  UINTN                            TotalRow,
  IN  CHAR16                           *Str,
  IN  UINTN                            StrPos,
  IN  UINTN                            Len
  )
{
  CHAR16  Backup;

  ASSERT (ConOut != NULL);
  ASSERT (Str != NULL);

  Backup = 0;
  if (Row >= 0) {
    ConOut->SetCursorPosition (ConOut, Column, Row);
    return;
  }

  if (Len - StrPos > Column * Row) {
    Backup                         = *(Str + StrPos + Column * Row);
    *(Str + StrPos + Column * Row) = 0;
  }

  EDBPrint (L"%s", Str + StrPos);
  if (Len - StrPos > Column * Row) {
    *(Str + StrPos + Column * Row) = Backup;
  }

  ConOut->SetCursorPosition (ConOut, 0, 0);
}

/**

  SetPageBreak.

**/
BOOLEAN
EFIAPI
SetPageBreak (
  VOID
  )
{
  EFI_INPUT_KEY  Key;
  CHAR16         Str[3];
  BOOLEAN        OmitPrint;

  //
  // Check
  //
  if (!mDebuggerPrivate.EnablePageBreak) {
    return FALSE;
  }

  gST->ConOut->OutputString (gST->ConOut, L"Press ENTER to continue, 'q' to exit:");

  OmitPrint = FALSE;
  //
  // Wait for user input
  //
  Str[0] = ' ';
  Str[1] = 0;
  Str[2] = 0;
  for ( ; ;) {
    WaitForSingleEvent (gST->ConIn->WaitForKey, 0);
    gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);

    //
    // handle control keys
    //
    if (Key.UnicodeChar == CHAR_NULL) {
      if (Key.ScanCode == SCAN_ESC) {
        gST->ConOut->OutputString (gST->ConOut, L"\r\n");
        OmitPrint = TRUE;
        break;
      }

      continue;
    }

    if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
      gST->ConOut->OutputString (gST->ConOut, L"\r\n");
      break;
    }

    //
    // Echo input
    //
    Str[1] = Key.UnicodeChar;
    if (Str[1] == CHAR_BACKSPACE) {
      continue;
    }

    gST->ConOut->OutputString (gST->ConOut, Str);

    if ((Str[1] == L'q') || (Str[1] == L'Q')) {
      OmitPrint = TRUE;
    } else {
      OmitPrint = FALSE;
    }

    Str[0] = CHAR_BACKSPACE;
  }

  return OmitPrint;
}

/**
  Print a Unicode string to the output device.

  @param  Format    A Null-terminated Unicode format string.
  @param  ...       The variable argument list that contains pointers to Null-
                    terminated Unicode strings to be printed

**/
UINTN
EFIAPI
EDBPrint (
  IN CONST CHAR16  *Format,
  ...
  )
{
  UINTN    Return;
  VA_LIST  Marker;
  CHAR16   Buffer[EFI_DEBUG_MAX_PRINT_BUFFER];

  VA_START (Marker, Format);
  Return = UnicodeVSPrint (Buffer, sizeof (Buffer), Format, Marker);
  VA_END (Marker);

  if (gST->ConOut != NULL) {
    //
    // To be extra safe make sure ConOut has been initialized
    //
    gST->ConOut->OutputString (gST->ConOut, Buffer);
  }

  return Return;
}

/**
  Print a Unicode string to the output buffer.

  @param  Buffer          A pointer to the output buffer for the produced Null-terminated
                          Unicode string.
  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
  @param  Format          A Null-terminated Unicode format string.
  @param  ...             The variable argument list that contains pointers to Null-
                          terminated Unicode strings to be printed

**/
UINTN
EFIAPI
EDBSPrint (
  OUT CHAR16        *Buffer,
  IN  INTN          BufferSize,
  IN  CONST CHAR16  *Format,
  ...
  )
{
  UINTN    Return;
  VA_LIST  Marker;

  ASSERT (BufferSize > 0);

  VA_START (Marker, Format);
  Return = UnicodeVSPrint (Buffer, (UINTN)BufferSize, Format, Marker);
  VA_END (Marker);

  return Return;
}

/**
  Print a Unicode string to the output buffer with specified offset..

  @param  Buffer          A pointer to the output buffer for the produced Null-terminated
                          Unicode string.
  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
  @param  Offset          The offset of the buffer.
  @param  Format          A Null-terminated Unicode format string.
  @param  ...             The variable argument list that contains pointers to Null-
                          terminated Unicode strings to be printed

**/
UINTN
EFIAPI
EDBSPrintWithOffset (
  OUT CHAR16        *Buffer,
  IN  INTN          BufferSize,
  IN  UINTN         Offset,
  IN  CONST CHAR16  *Format,
  ...
  )
{
  UINTN    Return;
  VA_LIST  Marker;

  ASSERT (BufferSize - (Offset * sizeof (CHAR16)) > 0);

  VA_START (Marker, Format);
  Return = UnicodeVSPrint (Buffer + Offset, (UINTN)(BufferSize - (Offset * sizeof (CHAR16))), Format, Marker);
  VA_END (Marker);

  return Return;
}
