/** @file
  Main file for Edit shell Debug1 function.

  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UefiShellDebug1CommandsLib.h"
#include "TextEditor.h"

/** Main function of the 'Edit' command.

  @param[in] Package    List of input parameter for the command.
**/
STATIC
SHELL_STATUS
MainCmdEdit (
  LIST_ENTRY  *Package
  )
{
  EFI_STATUS    Status;
  CHAR16        *Buffer;
  CONST CHAR16  *Cwd;
  CHAR16        *Nfs;
  CHAR16        *Spot;
  CONST CHAR16  *TempParam;

  Buffer = NULL;
  Nfs    = NULL;

  if (ShellCommandLineGetCount (Package) > 2) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"edit");
    return SHELL_INVALID_PARAMETER;
  }

  Cwd = gEfiShellProtocol->GetCurDir (NULL);
  if (Cwd == NULL) {
    Cwd = ShellGetEnvironmentVariable (L"path");
    if (Cwd != NULL) {
      Nfs = StrnCatGrow (&Nfs, NULL, Cwd+3, 0);
      if (Nfs != NULL) {
        Spot = StrStr (Nfs, L";");
        if (Spot != NULL) {
          *Spot = CHAR_NULL;
        }

        Spot = StrStr (Nfs, L"\\");
        if (Spot != NULL) {
          Spot[1] = CHAR_NULL;
        }

        gEfiShellProtocol->SetCurDir (NULL, Nfs);
        FreePool (Nfs);
      }
    }
  }

  Status = MainEditorInit ();

  if (EFI_ERROR (Status)) {
    gST->ConOut->ClearScreen (gST->ConOut);
    gST->ConOut->EnableCursor (gST->ConOut, TRUE);
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_EDIT_MAIN_INIT_FAILED), gShellDebug1HiiHandle);
    return SHELL_SUCCESS;
  }

  MainEditorBackup ();

  //
  // if editor launched with file named
  //
  if (ShellCommandLineGetCount (Package) == 2) {
    TempParam = ShellCommandLineGetRawValue (Package, 1);
    if (TempParam == NULL) {
      ASSERT (TempParam != NULL);
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"edit");
      return SHELL_INVALID_PARAMETER;
    } else {
      FileBufferSetFileName (TempParam);
    }
  }

  Status = FileBufferRead (MainEditor.FileBuffer->FileName, FALSE);
  if (!EFI_ERROR (Status)) {
    MainEditorRefresh ();

    Status = MainEditorKeyInput ();
  }

  if (Status != EFI_OUT_OF_RESOURCES) {
    //
    // back up the status string
    //
    Buffer = CatSPrint (NULL, L"%s", StatusBarGetString ());
  }

  MainEditorCleanup ();

  //
  // print editor exit code on screen
  //
  if (Status == EFI_SUCCESS) {
  } else if (Status == EFI_OUT_OF_RESOURCES) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"edit");
  } else {
    if (Buffer != NULL) {
      if (StrCmp (Buffer, L"") != 0) {
        //
        // print out the status string
        //
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_EDIT_MAIN_BUFFER), gShellDebug1HiiHandle, Buffer);
      } else {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_EDIT_MAIN_UNKNOWN_EDITOR_ERR), gShellDebug1HiiHandle);
      }
    } else {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_EDIT_MAIN_UNKNOWN_EDITOR_ERR), gShellDebug1HiiHandle);
    }
  }

  if (Status != EFI_OUT_OF_RESOURCES) {
    SHELL_FREE_NON_NULL (Buffer);
  }

  return SHELL_SUCCESS;
}

/**
  Function for 'edit' 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
ShellCommandRunEdit (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS    Status;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;
  LIST_ENTRY    *Package;

  //  SHELL_FILE_HANDLE   TempHandle;

  ShellStatus = SHELL_SUCCESS;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize ();
  ASSERT_EFI_ERROR (Status);

  Status = CommandInit ();
  ASSERT_EFI_ERROR (Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR (Status)) {
    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"edit", ProblemParam);
      FreePool (ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT (FALSE);
    }

    return ShellStatus;
  }

  ShellStatus = MainCmdEdit (Package);

  ShellCommandLineFreeVarList (Package);

  return ShellStatus;
}
