/** @file

  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
  Copyright (c) 2013 - 2021, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/
#include <Base.h>

#include <Library/BaseLib.h>
#include <Library/SemihostLib.h>

#include "SemihostPrivate.h"

BOOLEAN
SemihostConnectionSupported (
  VOID
  )
{
  return SEMIHOST_SUPPORTED;
}

RETURN_STATUS
SemihostFileOpen (
  IN  CHAR8   *FileName,
  IN  UINT32  Mode,
  OUT UINTN   *FileHandle
  )
{
  SEMIHOST_FILE_OPEN_BLOCK  OpenBlock;
  INT32                     Result;

  if (FileHandle == NULL) {
    return RETURN_INVALID_PARAMETER;
  }

  // Remove any leading separator (e.g.: '\'). EFI Shell adds one.
  if (*FileName == '\\') {
    FileName++;
  }

  OpenBlock.FileName   = FileName;
  OpenBlock.Mode       = Mode;
  OpenBlock.NameLength = AsciiStrLen (FileName);

  Result = SEMIHOST_SYS_OPEN (&OpenBlock);

  if (Result == -1) {
    return RETURN_NOT_FOUND;
  } else {
    *FileHandle = Result;
    return RETURN_SUCCESS;
  }
}

RETURN_STATUS
SemihostFileSeek (
  IN UINTN  FileHandle,
  IN UINTN  Offset
  )
{
  SEMIHOST_FILE_SEEK_BLOCK  SeekBlock;
  INT32                     Result;

  SeekBlock.Handle   = FileHandle;
  SeekBlock.Location = Offset;

  Result = SEMIHOST_SYS_SEEK (&SeekBlock);

  // Semihosting does not behave as documented. It returns the offset on
  // success.
  if (Result < 0) {
    return RETURN_ABORTED;
  } else {
    return RETURN_SUCCESS;
  }
}

RETURN_STATUS
SemihostFileRead (
  IN     UINTN  FileHandle,
  IN OUT UINTN  *Length,
  OUT    VOID   *Buffer
  )
{
  SEMIHOST_FILE_READ_WRITE_BLOCK  ReadBlock;
  UINT32                          Result;

  if ((Length == NULL) || (Buffer == NULL)) {
    return RETURN_INVALID_PARAMETER;
  }

  ReadBlock.Handle = FileHandle;
  ReadBlock.Buffer = Buffer;
  ReadBlock.Length = *Length;

  Result = SEMIHOST_SYS_READ (&ReadBlock);

  if ((*Length != 0) && (Result == *Length)) {
    return RETURN_ABORTED;
  } else {
    *Length -= Result;
    return RETURN_SUCCESS;
  }
}

RETURN_STATUS
SemihostFileWrite (
  IN     UINTN  FileHandle,
  IN OUT UINTN  *Length,
  IN     VOID   *Buffer
  )
{
  SEMIHOST_FILE_READ_WRITE_BLOCK  WriteBlock;

  if ((Length == NULL) || (Buffer == NULL)) {
    return RETURN_INVALID_PARAMETER;
  }

  WriteBlock.Handle = FileHandle;
  WriteBlock.Buffer = Buffer;
  WriteBlock.Length = *Length;

  *Length = SEMIHOST_SYS_WRITE (&WriteBlock);

  if (*Length != 0) {
    return RETURN_ABORTED;
  } else {
    return RETURN_SUCCESS;
  }
}

RETURN_STATUS
SemihostFileClose (
  IN UINTN  FileHandle
  )
{
  if (SEMIHOST_SYS_CLOSE (&FileHandle) == -1) {
    return RETURN_INVALID_PARAMETER;
  } else {
    return RETURN_SUCCESS;
  }
}

RETURN_STATUS
SemihostFileLength (
  IN  UINTN  FileHandle,
  OUT UINTN  *Length
  )
{
  INT32  Result;

  if (Length == NULL) {
    return RETURN_INVALID_PARAMETER;
  }

  Result = SEMIHOST_SYS_FLEN (&FileHandle);

  if (Result == -1) {
    return RETURN_ABORTED;
  } else {
    *Length = Result;
    return RETURN_SUCCESS;
  }
}

/**
  Get a temporary name for a file from the host running the debug agent.

  @param[out]  Buffer      Pointer to the buffer where the temporary name has to
                           be stored
  @param[in]   Identifier  File name identifier (integer in the range 0 to 255)
  @param[in]   Length      Length of the buffer to store the temporary name

  @retval  RETURN_SUCCESS            Temporary name returned
  @retval  RETURN_INVALID_PARAMETER  Invalid buffer address
  @retval  RETURN_ABORTED            Temporary name not returned

**/
RETURN_STATUS
SemihostFileTmpName (
  OUT  VOID   *Buffer,
  IN   UINT8  Identifier,
  IN   UINTN  Length
  )
{
  SEMIHOST_FILE_TMPNAME_BLOCK  TmpNameBlock;
  INT32                        Result;

  if (Buffer == NULL) {
    return RETURN_INVALID_PARAMETER;
  }

  TmpNameBlock.Buffer     = Buffer;
  TmpNameBlock.Identifier = Identifier;
  TmpNameBlock.Length     = Length;

  Result = SEMIHOST_SYS_TMPNAME (&TmpNameBlock);

  if (Result != 0) {
    return RETURN_ABORTED;
  } else {
    return RETURN_SUCCESS;
  }
}

RETURN_STATUS
SemihostFileRemove (
  IN CHAR8  *FileName
  )
{
  SEMIHOST_FILE_REMOVE_BLOCK  RemoveBlock;
  UINT32                      Result;

  // Remove any leading separator (e.g.: '\'). EFI Shell adds one.
  if (*FileName == '\\') {
    FileName++;
  }

  RemoveBlock.FileName   = FileName;
  RemoveBlock.NameLength = AsciiStrLen (FileName);

  Result = SEMIHOST_SYS_REMOVE (&RemoveBlock);

  if (Result == 0) {
    return RETURN_SUCCESS;
  } else {
    return RETURN_ABORTED;
  }
}

/**
  Rename a specified file.

  @param[in]  FileName     Name of the file to rename.
  @param[in]  NewFileName  The new name of the file.

  @retval  RETURN_SUCCESS            File Renamed
  @retval  RETURN_INVALID_PARAMETER  Either the current or the new name is not specified
  @retval  RETURN_ABORTED            Rename failed

**/
RETURN_STATUS
SemihostFileRename (
  IN  CHAR8  *FileName,
  IN  CHAR8  *NewFileName
  )
{
  SEMIHOST_FILE_RENAME_BLOCK  RenameBlock;
  INT32                       Result;

  if ((FileName == NULL) || (NewFileName == NULL)) {
    return RETURN_INVALID_PARAMETER;
  }

  RenameBlock.FileName          = FileName;
  RenameBlock.FileNameLength    = AsciiStrLen (FileName);
  RenameBlock.NewFileName       = NewFileName;
  RenameBlock.NewFileNameLength = AsciiStrLen (NewFileName);

  Result = SEMIHOST_SYS_RENAME (&RenameBlock);

  if (Result != 0) {
    return RETURN_ABORTED;
  } else {
    return RETURN_SUCCESS;
  }
}

CHAR8
SemihostReadCharacter (
  VOID
  )
{
  return SEMIHOST_SYS_READC ();
}

VOID
SemihostWriteCharacter (
  IN CHAR8  Character
  )
{
  SEMIHOST_SYS_WRITEC (&Character);
}

VOID
SemihostWriteString (
  IN CHAR8  *String
  )
{
  SEMIHOST_SYS_WRITE0 (String);
}

UINT32
SemihostSystem (
  IN CHAR8  *CommandLine
  )
{
  SEMIHOST_SYSTEM_BLOCK  SystemBlock;

  SystemBlock.CommandLine   = CommandLine;
  SystemBlock.CommandLength = AsciiStrLen (CommandLine);

  return SEMIHOST_SYS_SYSTEM (&SystemBlock);
}
