/** @file
  Main file for Parse shell level 2 function.

  (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UefiShellLevel2CommandsLib.h"

/**
  Check if data is coming from StdIn output.

  @param[in] None

  @retval TRUE  StdIn stream data available to parse
  @retval FALSE StdIn stream data is not available to parse.
**/
BOOLEAN
IsStdInDataAvailable (
  VOID
  )
{
  SHELL_FILE_HANDLE  FileHandle;
  EFI_STATUS         Status;
  CHAR16             CharBuffer;
  UINTN              CharSize;
  UINT64             OriginalFilePosition;

  Status               = EFI_SUCCESS;
  FileHandle           = NULL;
  OriginalFilePosition = 0;

  if (ShellOpenFileByName (L">i", &FileHandle, EFI_FILE_MODE_READ, 0) == EFI_SUCCESS) {
    CharSize = sizeof (CHAR16);
    gEfiShellProtocol->GetFilePosition (FileHandle, &OriginalFilePosition);
    Status = gEfiShellProtocol->ReadFile (FileHandle, &CharSize, &CharBuffer);
    if (EFI_ERROR (Status) || (CharSize != sizeof (CHAR16))) {
      return FALSE;
    }

    gEfiShellProtocol->SetFilePosition (FileHandle, OriginalFilePosition);
  }

  if (FileHandle == NULL) {
    return FALSE;
  } else {
    return TRUE;
  }
}

/**
  Handle stings for SFO Output with escape character ^ in a string
  1. Quotation marks in the string must be escaped by using a ^ character (i.e. ^").
  2. The ^ character may be inserted using ^^.

  @param[in]  String  The Unicode NULL-terminated string.

  @retval NewString   The new string handled for SFO.
**/
EFI_STRING
HandleStringWithEscapeCharForParse (
  IN      CHAR16  *String
  )
{
  EFI_STRING  NewStr;
  EFI_STRING  StrWalker;
  EFI_STRING  ReturnStr;

  if (String == NULL) {
    return NULL;
  }

  //
  // start to parse the input string.
  //
  NewStr = AllocateZeroPool (StrSize (String));
  if (NewStr == NULL) {
    return NULL;
  }

  ReturnStr = NewStr;
  StrWalker = String;
  while (*StrWalker != CHAR_NULL) {
    if ((*StrWalker == L'^') && ((*(StrWalker + 1) == L'^') || (*(StrWalker + 1) == L'"'))) {
      *NewStr = *(StrWalker + 1);
      StrWalker++;
    } else {
      *NewStr = *StrWalker;
    }

    StrWalker++;
    NewStr++;
  }

  return ReturnStr;
}

/**
  Do the actual parsing of the file.  the file should be SFO output from a
  shell command or a similar format.

  @param[in] FileName               The filename to open.
  @param[in] TableName              The name of the table to find.
  @param[in] ColumnIndex            The column number to get.
  @param[in] TableNameInstance      Which instance of the table to get (row).
  @param[in] ShellCommandInstance   Which instance of the command to get.
  @param[in] StreamingUnicode       Indicates Input file is StdIn Unicode streaming data or not

  @retval SHELL_NOT_FOUND     The requested instance was not found.
  @retval SHELL_SUCCESS       The operation was successful.
**/
SHELL_STATUS
PerformParsing (
  IN CONST CHAR16  *FileName,
  IN CONST CHAR16  *TableName,
  IN CONST UINTN   ColumnIndex,
  IN CONST UINTN   TableNameInstance,
  IN CONST UINTN   ShellCommandInstance,
  IN BOOLEAN       StreamingUnicode
  )
{
  SHELL_FILE_HANDLE  FileHandle;
  EFI_STATUS         Status;
  BOOLEAN            Ascii;
  UINTN              LoopVariable;
  UINTN              ColumnLoop;
  CHAR16             *TempLine;
  CHAR16             *ColumnPointer;
  SHELL_STATUS       ShellStatus;
  CHAR16             *TempSpot;
  CHAR16             *SfoString;

  ASSERT (FileName   != NULL);
  ASSERT (TableName  != NULL);

  ShellStatus = SHELL_SUCCESS;

  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
  if (EFI_ERROR (Status)) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"parse", FileName);
    ShellStatus = SHELL_NOT_FOUND;
  } else if (!EFI_ERROR (FileHandleIsDirectory (FileHandle))) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NOT_FILE), gShellLevel2HiiHandle, L"parse", FileName);
    ShellStatus = SHELL_NOT_FOUND;
  } else {
    for (LoopVariable = 0; LoopVariable < ShellCommandInstance && !ShellFileHandleEof (FileHandle);) {
      TempLine = ShellFileHandleReturnLine (FileHandle, &Ascii);

      if ((TempLine == NULL) || ((*TempLine == CHAR_NULL) && StreamingUnicode)) {
        break;
      }

      //
      // Search for "ShellCommand," in the file to start the SFO table
      // for a given ShellCommand.  The UEFI Shell spec does not specify
      // a space after the comma.
      //
      if (StrStr (TempLine, L"ShellCommand,") == TempLine) {
        LoopVariable++;
      }

      SHELL_FREE_NON_NULL (TempLine);
    }

    if (LoopVariable == ShellCommandInstance) {
      LoopVariable = 0;
      while (1) {
        TempLine = ShellFileHandleReturnLine (FileHandle, &Ascii);
        if (  (TempLine == NULL)
           || (*TempLine == CHAR_NULL)
           || (StrStr (TempLine, L"ShellCommand,") == TempLine))
        {
          SHELL_FREE_NON_NULL (TempLine);
          break;
        }

        if (StrStr (TempLine, TableName) == TempLine) {
          LoopVariable++;
          if (  (LoopVariable == TableNameInstance)
             || (TableNameInstance == (UINTN)-1))
          {
            for (ColumnLoop = 1, ColumnPointer = TempLine; ColumnLoop < ColumnIndex && ColumnPointer != NULL && *ColumnPointer != CHAR_NULL; ColumnLoop++) {
              ColumnPointer = StrStr (ColumnPointer, L",\"");
              if ((ColumnPointer != NULL) && (*ColumnPointer != CHAR_NULL)) {
                ColumnPointer++;
              }
            }

            if (ColumnLoop == ColumnIndex) {
              if (ColumnPointer == NULL) {
                ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"parse", L"Column Index");
                ShellStatus = SHELL_INVALID_PARAMETER;
              } else {
                TempSpot = StrStr (ColumnPointer, L",\"");
                if (TempSpot != NULL) {
                  *TempSpot = CHAR_NULL;
                }

                while (ColumnPointer != NULL && *ColumnPointer != CHAR_NULL && ColumnPointer[0] == L' ') {
                  ColumnPointer++;
                }

                if ((ColumnPointer != NULL) && (*ColumnPointer != CHAR_NULL) && (ColumnPointer[0] == L'\"')) {
                  ColumnPointer++;
                }

                if ((ColumnPointer != NULL) && (*ColumnPointer != CHAR_NULL) && (ColumnPointer[StrLen (ColumnPointer) - 1] == L'\"')) {
                  ColumnPointer[StrLen (ColumnPointer) - 1] = CHAR_NULL;
                }

                SfoString = HandleStringWithEscapeCharForParse (ColumnPointer);
                if (SfoString != NULL) {
                  ShellPrintDefaultEx (L"%s\r\n", SfoString);
                  SHELL_FREE_NON_NULL (SfoString);
                }
              }
            }
          }
        }

        SHELL_FREE_NON_NULL (TempLine);
      }
    }
  }

  return (ShellStatus);
}

STATIC CONST SHELL_PARAM_ITEM  ParamList[] = {
  { L"-i", TypeValue },
  { L"-s", TypeValue },
  { NULL,  TypeMax   }
};

/** Main function of the 'Parse' command.

  @param[in] Package    List of input parameter for the command.
**/
STATIC
SHELL_STATUS
MainCmdParse (
  LIST_ENTRY  *Package
  )
{
  CONST CHAR16  *FileName;
  CONST CHAR16  *TableName;
  CONST CHAR16  *ColumnString;
  SHELL_STATUS  ShellStatus;
  UINTN         ShellCommandInstance;
  UINTN         TableNameInstance;
  BOOLEAN       StreamingUnicode;

  ShellStatus      = SHELL_SUCCESS;
  StreamingUnicode = FALSE;

  StreamingUnicode = IsStdInDataAvailable ();
  if ((!StreamingUnicode && (ShellCommandLineGetCount (Package) < 4)) ||
      (ShellCommandLineGetCount (Package) < 3))
  {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"parse");
    return SHELL_INVALID_PARAMETER;
  } else if ((StreamingUnicode && (ShellCommandLineGetCount (Package) > 3)) ||
             (ShellCommandLineGetCount (Package) > 4))
  {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"parse");
    return SHELL_INVALID_PARAMETER;
  }

  if (StreamingUnicode) {
    FileName     = L">i";
    TableName    = ShellCommandLineGetRawValue (Package, 1);
    ColumnString = ShellCommandLineGetRawValue (Package, 2);
  } else {
    FileName     = ShellCommandLineGetRawValue (Package, 1);
    TableName    = ShellCommandLineGetRawValue (Package, 2);
    ColumnString = ShellCommandLineGetRawValue (Package, 3);
  }

  if (ShellCommandLineGetValue (Package, L"-i") == NULL) {
    TableNameInstance = (UINTN)-1;
  } else {
    TableNameInstance = ShellStrToUintn (ShellCommandLineGetValue (Package, L"-i"));
  }

  if (ShellCommandLineGetValue (Package, L"-s") == NULL) {
    ShellCommandInstance = 1;
  } else {
    ShellCommandInstance = ShellStrToUintn (ShellCommandLineGetValue (Package, L"-s"));
  }

  if ((FileName != NULL) && (TableName != NULL) && (ColumnString != NULL)) {
    ShellStatus = PerformParsing (FileName, TableName, ShellStrToUintn (ColumnString), TableNameInstance, ShellCommandInstance, StreamingUnicode);
  } else {
    ShellStatus = SHELL_INVALID_PARAMETER;
  }

  return ShellStatus;
}

/**
  Function for 'parse' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunParse (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS    Status;
  LIST_ENTRY    *Package;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;

  ShellStatus  = SHELL_SUCCESS;
  ProblemParam = NULL;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize ();
  ASSERT_EFI_ERROR (Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParseEx (ParamList, &Package, &ProblemParam, TRUE, FALSE);
  if (EFI_ERROR (Status)) {
    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"parse", ProblemParam);
      FreePool (ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT (FALSE);
    }

    return ShellStatus;
  }

  ShellStatus = MainCmdParse (Package);

  //
  // free the command line package
  //
  ShellCommandLineFreeVarList (Package);

  return (ShellStatus);
}
