/** @file
  Functions to deal with file buffer.

  Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "HexEditor.h"

extern EFI_HANDLE                 HImageHandleBackup;
extern HEFI_EDITOR_BUFFER_IMAGE   HBufferImage;

extern BOOLEAN                    HBufferImageNeedRefresh;
extern BOOLEAN                    HBufferImageOnlyLineNeedRefresh;
extern BOOLEAN                    HBufferImageMouseNeedRefresh;

extern HEFI_EDITOR_GLOBAL_EDITOR  HMainEditor;

HEFI_EDITOR_FILE_IMAGE            HFileImage;
HEFI_EDITOR_FILE_IMAGE            HFileImageBackupVar;

//
// for basic initialization of HFileImage
//
HEFI_EDITOR_BUFFER_IMAGE          HFileImageConst = {
  NULL,
  0,
  FALSE
};

/**
  Initialization function for HFileImage

  @retval EFI_SUCCESS     The operation was successful.
**/
EFI_STATUS
HFileImageInit (
  VOID
  )
{
  //
  // basically initialize the HFileImage
  //
  CopyMem (&HFileImage, &HFileImageConst, sizeof (HFileImage));

  CopyMem (
    &HFileImageBackupVar,
    &HFileImageConst,
    sizeof (HFileImageBackupVar)
    );

  return EFI_SUCCESS;
}

/**
  Backup function for HFileImage. Only a few fields need to be backup.
  This is for making the file buffer refresh as few as possible.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
HFileImageBackup (
  VOID
  )
{
  SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName);
  HFileImageBackupVar.FileName = CatSPrint(NULL, L"%s", HFileImage.FileName);
  if (HFileImageBackupVar.FileName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Cleanup function for HFileImage.

  @retval EFI_SUCCESS           The operation was successful.
**/
EFI_STATUS
HFileImageCleanup (
  VOID
  )
{

  SHELL_FREE_NON_NULL (HFileImage.FileName);
  SHELL_FREE_NON_NULL (HFileImageBackupVar.FileName);

  return EFI_SUCCESS;
}

/**
  Set FileName field in HFileImage

  @param[in] Str  File name to set.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
HFileImageSetFileName (
  IN CONST CHAR16 *Str
  )
{
  if (Str == HFileImage.FileName) {
    //
    // This function might be called using HFileImage.FileName as Str.
    // Directly return without updating HFileImage.FileName.
    //
    return EFI_SUCCESS;
  }
  //
  // free the old file name
  //
  SHELL_FREE_NON_NULL (HFileImage.FileName);
  HFileImage.FileName = AllocateCopyPool (StrSize (Str), Str);
  if (HFileImage.FileName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Read a file from disk into HBufferImage.

  @param[in] FileName     filename to read.
  @param[in] Recover      if is for recover, no information print.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @retval EFI_LOAD_ERROR        A load error occurred.
**/
EFI_STATUS
HFileImageRead (
  IN CONST CHAR16  *FileName,
  IN BOOLEAN Recover
  )
{
  HEFI_EDITOR_LINE                *Line;
  UINT8                           *Buffer;
  CHAR16                          *UnicodeBuffer;
  EFI_STATUS                      Status;

  //
  // variable initialization
  //
  Line                    = NULL;

  //
  // in this function, when you return error ( except EFI_OUT_OF_RESOURCES )
  // you should set status string
  // since this function maybe called before the editorhandleinput loop
  // so any error will cause editor return
  // so if you want to print the error status
  // you should set the status string
  //
  Status = ReadFileIntoBuffer (FileName, (VOID**)&Buffer, &HFileImage.Size, &HFileImage.ReadOnly);
  //
  // NULL pointer is only also a failure for a non-zero file size.
  //
  if ((EFI_ERROR(Status)) || (Buffer == NULL && HFileImage.Size != 0)) {
    UnicodeBuffer = CatSPrint(NULL, L"Read error on file %s: %r", FileName, Status);
    if (UnicodeBuffer == NULL) {
      SHELL_FREE_NON_NULL(Buffer);
      return EFI_OUT_OF_RESOURCES;
    }

    StatusBarSetStatusString (UnicodeBuffer);
    FreePool (UnicodeBuffer);
    return EFI_OUT_OF_RESOURCES;
  }

  HFileImageSetFileName (FileName);

  //
  // free the old lines
  //
  HBufferImageFree ();

  Status = HBufferImageBufferToList (Buffer, HFileImage.Size);
  SHELL_FREE_NON_NULL (Buffer);
  if (EFI_ERROR (Status)) {
    StatusBarSetStatusString (L"Error parsing file.");
    return Status;
  }

  HBufferImage.DisplayPosition.Row    = 2;
  HBufferImage.DisplayPosition.Column = 10;
  HBufferImage.MousePosition.Row      = 2;
  HBufferImage.MousePosition.Column   = 10;
  HBufferImage.LowVisibleRow          = 1;
  HBufferImage.HighBits               = TRUE;
  HBufferImage.BufferPosition.Row     = 1;
  HBufferImage.BufferPosition.Column  = 1;
  HBufferImage.BufferType = FileTypeFileBuffer;

  if (!Recover) {
    UnicodeBuffer = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines);
    if (UnicodeBuffer == NULL) {
      SHELL_FREE_NON_NULL(Buffer);
      return EFI_OUT_OF_RESOURCES;
    }

    StatusBarSetStatusString (UnicodeBuffer);
    FreePool (UnicodeBuffer);

    HMainEditor.SelectStart = 0;
    HMainEditor.SelectEnd   = 0;
  }

  //
  // has line
  //
  if (HBufferImage.Lines != 0) {
    HBufferImage.CurrentLine = CR (HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
  } else {
    //
    // create a dummy line
    //
    Line = HBufferImageCreateLine ();
    if (Line == NULL) {
      SHELL_FREE_NON_NULL(Buffer);
      return EFI_OUT_OF_RESOURCES;
    }

    HBufferImage.CurrentLine = Line;
  }

  HBufferImage.Modified           = FALSE;
  HBufferImageNeedRefresh         = TRUE;
  HBufferImageOnlyLineNeedRefresh = FALSE;
  HBufferImageMouseNeedRefresh    = TRUE;

  return EFI_SUCCESS;
}

/**
  Save lines in HBufferImage to disk.

  @param[in] FileName     The file name.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @retval EFI_LOAD_ERROR        A load error occurred.
**/
EFI_STATUS
HFileImageSave (
  IN CHAR16 *FileName
  )
{

  LIST_ENTRY                      *Link;
  HEFI_EDITOR_LINE                *Line;
  CHAR16                          *Str;
  EFI_STATUS                      Status;
  UINTN                           NumLines;
  SHELL_FILE_HANDLE                 FileHandle;
  UINTN                           TotalSize;
  UINT8                           *Buffer;
  UINT8                           *Ptr;
  EDIT_FILE_TYPE                  BufferTypeBackup;

  BufferTypeBackup        = HBufferImage.BufferType;
  HBufferImage.BufferType = FileTypeFileBuffer;

  //
  // if is the old file
  //
  if (HFileImage.FileName != NULL && FileName != NULL && StrCmp (FileName, HFileImage.FileName) == 0) {
    //
    // check whether file exists on disk
    //
    if (ShellIsFile(FileName) == EFI_SUCCESS) {
      //
      // current file exists on disk
      // so if not modified, then not save
      //
      if (HBufferImage.Modified == FALSE) {
        return EFI_SUCCESS;
      }
      //
      // if file is read-only, set error
      //
      if (HFileImage.ReadOnly == TRUE) {
        StatusBarSetStatusString (L"Read Only File Can Not Be Saved");
        return EFI_SUCCESS;
      }
    }
  }

   if (ShellIsDirectory(FileName) == EFI_SUCCESS) {
    StatusBarSetStatusString (L"Directory Can Not Be Saved");
    return EFI_LOAD_ERROR;
  }

  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);

  if (!EFI_ERROR (Status)) {
    //
    // the file exits, delete it
    //
    Status = ShellDeleteFile (&FileHandle);
    if (EFI_ERROR (Status) || Status == EFI_WARN_DELETE_FAILURE) {
      StatusBarSetStatusString (L"Write File Failed");
      return EFI_LOAD_ERROR;
    }
 }

  //
  // write all the lines back to disk
  //
  NumLines  = 0;
  TotalSize = 0;
  for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {
    Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);

    if (Line->Size != 0) {
      TotalSize += Line->Size;
    }
    //
    // end of if Line -> Size != 0
    //
    NumLines++;
  }
  //
  // end of for Link
  //
  Buffer = AllocateZeroPool (TotalSize);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Ptr = Buffer;
  for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {
    Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);

    if (Line->Size != 0) {
      CopyMem (Ptr, Line->Buffer, Line->Size);
      Ptr += Line->Size;
    }
    //
    // end of if Line -> Size != 0
    //
  }


  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);

  if (EFI_ERROR (Status)) {
    StatusBarSetStatusString (L"Create File Failed");
    return EFI_LOAD_ERROR;
  }

  Status = ShellWriteFile (FileHandle, &TotalSize, Buffer);
  FreePool (Buffer);
  if (EFI_ERROR (Status)) {
    ShellDeleteFile (&FileHandle);
    return EFI_LOAD_ERROR;
  }

  ShellCloseFile(&FileHandle);

  HBufferImage.Modified = FALSE;

  //
  // set status string
  //
  Str = CatSPrint(NULL, L"%d Lines Written", NumLines);
  StatusBarSetStatusString (Str);
  FreePool (Str);

  //
  // now everything is ready , you can set the new file name to filebuffer
  //
  if ((BufferTypeBackup != FileTypeFileBuffer && FileName != NULL) ||
     (FileName != NULL && HFileImage.FileName != NULL && StringNoCaseCompare (&FileName, &HFileImage.FileName) != 0)){
    //
    // not the same
    //
    HFileImageSetFileName (FileName);
    if (HFileImage.FileName == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  HFileImage.ReadOnly = FALSE;

  return EFI_SUCCESS;
}
