//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/File.h"

#include <cerrno>
#include <climits>
#include <cstdarg>
#include <cstdio>
#include <fcntl.h>
#include <optional>
#include <sys/stat.h>

#include "lldb/Host/Config.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/VASPrintf.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/raw_ostream.h"

using namespace lldb;
using namespace lldb_private;
using llvm::Expected;

Expected<const char *>
File::GetStreamOpenModeFromOptions(File::OpenOptions options) {
  File::OpenOptions rw =
      options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly |
                 File::eOpenOptionReadWrite);

  if (options & File::eOpenOptionAppend) {
    if (rw == File::eOpenOptionReadWrite) {
      if (options & File::eOpenOptionCanCreateNewOnly)
        return "a+x";
      else
        return "a+";
    } else if (rw == File::eOpenOptionWriteOnly) {
      if (options & File::eOpenOptionCanCreateNewOnly)
        return "ax";
      else
        return "a";
    }
  } else if (rw == File::eOpenOptionReadWrite) {
    if (options & File::eOpenOptionCanCreate) {
      if (options & File::eOpenOptionCanCreateNewOnly)
        return "w+x";
      else
        return "w+";
    } else
      return "r+";
  } else if (rw == File::eOpenOptionWriteOnly) {
    return "w";
  } else if (rw == File::eOpenOptionReadOnly) {
    return "r";
  }
  return llvm::createStringError(
      llvm::inconvertibleErrorCode(),
      "invalid options, cannot convert to mode string");
}

Expected<File::OpenOptions> File::GetOptionsFromMode(llvm::StringRef mode) {
  OpenOptions opts =
      llvm::StringSwitch<OpenOptions>(mode)
          .Cases({"r", "rb"}, eOpenOptionReadOnly)
          .Cases({"w", "wb"}, eOpenOptionWriteOnly)
          .Cases({"a", "ab"}, eOpenOptionWriteOnly | eOpenOptionAppend |
                                  eOpenOptionCanCreate)
          .Cases({"r+", "rb+", "r+b"}, eOpenOptionReadWrite)
          .Cases({"w+", "wb+", "w+b"}, eOpenOptionReadWrite |
                                           eOpenOptionCanCreate |
                                           eOpenOptionTruncate)
          .Cases({"a+", "ab+", "a+b"}, eOpenOptionReadWrite |
                                           eOpenOptionAppend |
                                           eOpenOptionCanCreate)
          .Default(eOpenOptionInvalid);
  if (opts != eOpenOptionInvalid)
    return opts;
  return llvm::createStringError(
      llvm::inconvertibleErrorCode(),
      "invalid mode, cannot convert to File::OpenOptions");
}

int File::kInvalidDescriptor = -1;
FILE *File::kInvalidStream = nullptr;

Status File::Read(void *buf, size_t &num_bytes) {
  return std::error_code(ENOTSUP, std::system_category());
}
Status File::Write(const void *buf, size_t &num_bytes) {
  return std::error_code(ENOTSUP, std::system_category());
}

bool File::IsValid() const { return false; }

Status File::Close() { return Flush(); }

IOObject::WaitableHandle File::GetWaitableHandle() {
  return IOObject::kInvalidHandleValue;
}

Status File::GetFileSpec(FileSpec &file_spec) const {
  file_spec.Clear();
  return std::error_code(ENOTSUP, std::system_category());
}

int File::GetDescriptor() const { return kInvalidDescriptor; }

FILE *File::GetStream() { return nullptr; }

off_t File::SeekFromStart(off_t offset, Status *error_ptr) {
  if (error_ptr)
    *error_ptr = std::error_code(ENOTSUP, std::system_category());
  return -1;
}

off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) {
  if (error_ptr)
    *error_ptr = std::error_code(ENOTSUP, std::system_category());
  return -1;
}

off_t File::SeekFromEnd(off_t offset, Status *error_ptr) {
  if (error_ptr)
    *error_ptr = std::error_code(ENOTSUP, std::system_category());
  return -1;
}

Status File::Read(void *dst, size_t &num_bytes, off_t &offset) {
  return std::error_code(ENOTSUP, std::system_category());
}

Status File::Write(const void *src, size_t &num_bytes, off_t &offset) {
  return std::error_code(ENOTSUP, std::system_category());
}

Status File::Flush() { return Status(); }

Status File::Sync() { return Flush(); }

void File::CalculateInteractiveAndTerminal() {
  // The base class has no descriptor of its own; concrete subclasses probe
  // the platform.  Default to "not a terminal" so callers see consistent
  // values when they didn't override.
  m_is_interactive = eLazyBoolNo;
  m_is_real_terminal = eLazyBoolNo;
  m_supports_colors = eLazyBoolNo;
}

bool File::GetIsInteractive() {
  if (m_is_interactive == eLazyBoolCalculate)
    CalculateInteractiveAndTerminal();
  return m_is_interactive == eLazyBoolYes;
}

bool File::GetIsRealTerminal() {
  if (m_is_real_terminal == eLazyBoolCalculate)
    CalculateInteractiveAndTerminal();
  return m_is_real_terminal == eLazyBoolYes;
}

bool File::GetIsTerminalWithColors() {
  if (m_supports_colors == eLazyBoolCalculate)
    CalculateInteractiveAndTerminal();
  return m_supports_colors == eLazyBoolYes;
}

size_t File::Printf(const char *format, ...) {
  va_list args;
  va_start(args, format);
  size_t result = PrintfVarArg(format, args);
  va_end(args);
  return result;
}

size_t File::PrintfVarArg(const char *format, va_list args) {
  llvm::SmallString<0> s;
  if (VASprintf(s, format, args)) {
    size_t written = s.size();
    Write(s.data(), written);
    return written;
  }
  return 0;
}

Expected<File::OpenOptions> File::GetOptions() const {
  return llvm::createStringError(
      llvm::inconvertibleErrorCode(),
      "GetOptions() not implemented for this File class");
}

uint32_t File::GetPermissions(Status &error) const {
  int fd = GetDescriptor();
  if (!DescriptorIsValid(fd)) {
    error = std::error_code(ENOTSUP, std::system_category());
    return 0;
  }
  struct stat file_stats;
  if (::fstat(fd, &file_stats) == -1) {
    error = Status::FromErrno();
    return 0;
  }
  error.Clear();
  return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
}

NativeFileBase::NativeFileBase() = default;

NativeFileBase::NativeFileBase(FILE *fh, OpenOptions options,
                               bool transfer_ownership)
    : m_stream(fh), m_options(options), m_own_stream(transfer_ownership) {}

NativeFileBase::NativeFileBase(int fd, OpenOptions options,
                               bool transfer_ownership)
    : m_descriptor(fd), m_own_descriptor(transfer_ownership),
      m_options(options) {}

bool NativeFileBase::IsValid() const {
  std::scoped_lock<std::mutex, std::mutex> lock(m_descriptor_mutex,
                                                m_stream_mutex);
  return DescriptorIsValidUnlocked() || StreamIsValidUnlocked();
}

Expected<File::OpenOptions> NativeFileBase::GetOptions() const {
  return m_options;
}

int NativeFileBase::Fileno(FILE *fh) const { return ::fileno(fh); }

int NativeFileBase::Dup(int fd) const { return ::dup(fd); }

int NativeFileBase::GetDescriptor() const {
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
    return m_descriptor;
  }

  // Don't open the file descriptor if we don't need to, just get it from the
  // stream if we have one.
  if (ValueGuard stream_guard = StreamIsValid()) {
    return Fileno(m_stream);
  }

  // Invalid descriptor and invalid stream, return invalid descriptor.
  return kInvalidDescriptor;
}

IOObject::WaitableHandle NativeFileBase::GetWaitableHandle() {
  // The mapping from descriptor/stream to a poll-able WaitableHandle is
  // platform-specific (an int on POSIX, a HANDLE on Windows).  Subclasses
  // override; the base returns the portable invalid sentinel.
  return IOObject::kInvalidHandleValue;
}

FILE *NativeFileBase::GetStream() {
  ValueGuard stream_guard = StreamIsValid();
  if (stream_guard)
    return m_stream;

  ValueGuard descriptor_guard = DescriptorIsValid();
  if (!descriptor_guard)
    return m_stream;

  auto mode_or_err = GetStreamOpenModeFromOptions(m_options);
  if (!mode_or_err) {
    LLDB_LOG_ERROR(GetLog(LLDBLog::Object), mode_or_err.takeError(),
                   "Failed to get stream options: {0}");
    return m_stream;
  }
  const char *mode = *mode_or_err;

  if (!m_own_descriptor) {
    // We must duplicate the file descriptor if we don't own it because
    // when you call fdopen, the stream will own the fd.
    m_descriptor = Dup(m_descriptor);
    m_own_descriptor = true;
  }

  m_stream = llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor, mode);

  // If we got a stream, then we own the stream and should no longer own
  // the descriptor because fclose() will close it for us.
  if (m_stream) {
    m_own_stream = true;
    m_own_descriptor = false;
    OnStreamOpened();
  }

  return m_stream;
}

Status NativeFileBase::Close() {
  std::scoped_lock<std::mutex, std::mutex> lock(m_descriptor_mutex,
                                                m_stream_mutex);

  Status error;

  if (StreamIsValidUnlocked()) {
    if (m_own_stream) {
      if (::fclose(m_stream) == EOF)
        error = Status::FromErrno();
    } else {
      File::OpenOptions rw =
          m_options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly |
                       File::eOpenOptionReadWrite);

      if (rw == eOpenOptionWriteOnly || rw == eOpenOptionReadWrite) {
        if (::fflush(m_stream) == EOF)
          error = Status::FromErrno();
      }
    }
  }

  if (DescriptorIsValidUnlocked() && m_own_descriptor) {
    if (::close(m_descriptor) != 0)
      error = Status::FromErrno();
  }

  m_stream = kInvalidStream;
  m_own_stream = false;
  m_descriptor = kInvalidDescriptor;
  m_own_descriptor = false;
  m_options = OpenOptions(0);
  m_is_interactive = eLazyBoolCalculate;
  m_is_real_terminal = eLazyBoolCalculate;
  return error;
}

Status NativeFileBase::GetFileSpec(FileSpec &file_spec) const {
  // Default: not supported.  POSIX subclass overrides with F_GETPATH /
  // /proc/self/fd lookups; the Windows subclass currently has no equivalent
  // and inherits this behaviour.
  file_spec.Clear();
  return Status::FromErrorString(
      "NativeFile::GetFileSpec is not supported on this platform");
}

off_t NativeFileBase::SeekFromStart(off_t offset, Status *error_ptr) {
  off_t result = 0;
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
    result = ::lseek(m_descriptor, offset, SEEK_SET);

    if (error_ptr) {
      if (result == -1)
        *error_ptr = Status::FromErrno();
      else
        error_ptr->Clear();
    }
    return result;
  }

  if (ValueGuard stream_guard = StreamIsValid()) {
    result = ::fseek(m_stream, offset, SEEK_SET);

    if (error_ptr) {
      if (result == -1)
        *error_ptr = Status::FromErrno();
      else
        error_ptr->Clear();
    }
    return result;
  }

  if (error_ptr)
    *error_ptr = Status::FromErrorString("invalid file handle");
  return result;
}

off_t NativeFileBase::SeekFromCurrent(off_t offset, Status *error_ptr) {
  off_t result = -1;
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
    result = ::lseek(m_descriptor, offset, SEEK_CUR);

    if (error_ptr) {
      if (result == -1)
        *error_ptr = Status::FromErrno();
      else
        error_ptr->Clear();
    }
    return result;
  }

  if (ValueGuard stream_guard = StreamIsValid()) {
    result = ::fseek(m_stream, offset, SEEK_CUR);

    if (error_ptr) {
      if (result == -1)
        *error_ptr = Status::FromErrno();
      else
        error_ptr->Clear();
    }
    return result;
  }

  if (error_ptr)
    *error_ptr = Status::FromErrorString("invalid file handle");
  return result;
}

off_t NativeFileBase::SeekFromEnd(off_t offset, Status *error_ptr) {
  off_t result = -1;
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
    result = ::lseek(m_descriptor, offset, SEEK_END);

    if (error_ptr) {
      if (result == -1)
        *error_ptr = Status::FromErrno();
      else
        error_ptr->Clear();
    }
    return result;
  }

  if (ValueGuard stream_guard = StreamIsValid()) {
    result = ::fseek(m_stream, offset, SEEK_END);

    if (error_ptr) {
      if (result == -1)
        *error_ptr = Status::FromErrno();
      else
        error_ptr->Clear();
    }
    return result;
  }

  if (error_ptr)
    *error_ptr = Status::FromErrorString("invalid file handle");
  return result;
}

Status NativeFileBase::Flush() {
  Status error;
  if (ValueGuard stream_guard = StreamIsValid()) {
    if (llvm::sys::RetryAfterSignal(EOF, ::fflush, m_stream) == EOF)
      error = Status::FromErrno();
    return error;
  }

  {
    ValueGuard descriptor_guard = DescriptorIsValid();
    if (!descriptor_guard)
      error = Status::FromErrorString("invalid file handle");
  }
  return error;
}

#if defined(__APPLE__)
// Darwin kernels only can read/write <= INT_MAX bytes
#define MAX_READ_SIZE INT_MAX
#define MAX_WRITE_SIZE INT_MAX
#endif

Status NativeFileBase::Read(void *buf, size_t &num_bytes) {
  Status error;

  // Ensure the file is open for reading.
  if ((m_options & File::OpenOptionsModeMask) == eOpenOptionWriteOnly)
    return Status(std::make_error_code(std::errc::bad_file_descriptor));

#if defined(MAX_READ_SIZE)
  if (num_bytes > MAX_READ_SIZE) {
    uint8_t *p = (uint8_t *)buf;
    size_t bytes_left = num_bytes;
    // Init the num_bytes read to zero
    num_bytes = 0;

    while (bytes_left > 0) {
      size_t curr_num_bytes;
      if (bytes_left > MAX_READ_SIZE)
        curr_num_bytes = MAX_READ_SIZE;
      else
        curr_num_bytes = bytes_left;

      error = Read(p + num_bytes, curr_num_bytes);

      // Update how many bytes were read
      num_bytes += curr_num_bytes;
      if (bytes_left < curr_num_bytes)
        bytes_left = 0;
      else
        bytes_left -= curr_num_bytes;

      if (error.Fail())
        break;
    }
    return error;
  }
#endif

  ssize_t bytes_read = -1;
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
    bytes_read =
        llvm::sys::RetryAfterSignal(-1, ::read, m_descriptor, buf, num_bytes);
    if (bytes_read == -1) {
      error = Status::FromErrno();
      num_bytes = 0;
    } else
      num_bytes = bytes_read;
    return error;
  }

  if (ValueGuard file_lock = StreamIsValid()) {
    bytes_read = ::fread(buf, 1, num_bytes, m_stream);

    if (bytes_read == 0) {
      if (::feof(m_stream))
        error = Status::FromErrorString("feof");
      else if (::ferror(m_stream))
        error = Status::FromErrorString("ferror");
      num_bytes = 0;
    } else
      num_bytes = bytes_read;
    return error;
  }

  num_bytes = 0;
  error = Status::FromErrorString("invalid file handle");
  return error;
}

Status NativeFileBase::Write(const void *buf, size_t &num_bytes) {
  Status error;

  // Ensure the file is open for writing.
  if ((m_options & File::OpenOptionsModeMask) == File::eOpenOptionReadOnly)
    return Status(std::make_error_code(std::errc::bad_file_descriptor));

#if defined(MAX_WRITE_SIZE)
  if (num_bytes > MAX_WRITE_SIZE) {
    const uint8_t *p = (const uint8_t *)buf;
    size_t bytes_left = num_bytes;
    // Init the num_bytes written to zero
    num_bytes = 0;

    while (bytes_left > 0) {
      size_t curr_num_bytes;
      if (bytes_left > MAX_WRITE_SIZE)
        curr_num_bytes = MAX_WRITE_SIZE;
      else
        curr_num_bytes = bytes_left;

      error = Write(p + num_bytes, curr_num_bytes);

      // Update how many bytes were read
      num_bytes += curr_num_bytes;
      if (bytes_left < curr_num_bytes)
        bytes_left = 0;
      else
        bytes_left -= curr_num_bytes;

      if (error.Fail())
        break;
    }
    return error;
  }
#endif

  ssize_t bytes_written = -1;
  if (ValueGuard descriptor_guard = DescriptorIsValid()) {
    bytes_written =
        llvm::sys::RetryAfterSignal(-1, ::write, m_descriptor, buf, num_bytes);
    if (bytes_written == -1) {
      error = Status::FromErrno();
      num_bytes = 0;
    } else
      num_bytes = bytes_written;
    return error;
  }

  if (ValueGuard stream_guard = StreamIsValid()) {
    if (TryWriteStreamUnlocked(buf, num_bytes, error))
      return error;
    bytes_written = ::fwrite(buf, 1, num_bytes, m_stream);

    if (bytes_written == 0) {
      if (::feof(m_stream))
        error = Status::FromErrorString("feof");
      else if (::ferror(m_stream))
        error = Status::FromErrorString("ferror");
      num_bytes = 0;
    } else
      num_bytes = bytes_written;
    return error;
  }

  num_bytes = 0;
  error = Status::FromErrorString("invalid file handle");
  return error;
}

size_t NativeFileBase::PrintfVarArg(const char *format, va_list args) {
  if (StreamIsValid()) {
    return ::vfprintf(m_stream, format, args);
  } else {
    return File::PrintfVarArg(format, args);
  }
}

mode_t File::ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options) {
  mode_t mode = 0;
  File::OpenOptions rw =
      open_options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly |
                      File::eOpenOptionReadWrite);
  if (rw == eOpenOptionReadWrite)
    mode |= O_RDWR;
  else if (rw == eOpenOptionWriteOnly)
    mode |= O_WRONLY;
  else if (rw == eOpenOptionReadOnly)
    mode |= O_RDONLY;

  if (open_options & eOpenOptionAppend)
    mode |= O_APPEND;

  if (open_options & eOpenOptionTruncate)
    mode |= O_TRUNC;

  if (open_options & eOpenOptionNonBlocking)
    mode |= O_NONBLOCK;

  if (open_options & eOpenOptionCanCreateNewOnly)
    mode |= O_CREAT | O_EXCL;
  else if (open_options & eOpenOptionCanCreate)
    mode |= O_CREAT;

  return mode;
}

llvm::Expected<SerialPort::Options>
SerialPort::OptionsFromURL(llvm::StringRef urlqs) {
  SerialPort::Options serial_options;
  for (llvm::StringRef x : llvm::split(urlqs, '&')) {
    if (x.consume_front("baud=")) {
      unsigned int baud_rate;
      if (!llvm::to_integer(x, baud_rate, 10))
        return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                       "Invalid baud rate: %s",
                                       x.str().c_str());
      serial_options.BaudRate = baud_rate;
    } else if (x.consume_front("parity=")) {
      serial_options.Parity =
          llvm::StringSwitch<std::optional<Terminal::Parity>>(x)
              .Case("no", Terminal::Parity::No)
              .Case("even", Terminal::Parity::Even)
              .Case("odd", Terminal::Parity::Odd)
              .Case("mark", Terminal::Parity::Mark)
              .Case("space", Terminal::Parity::Space)
              .Default(std::nullopt);
      if (!serial_options.Parity)
        return llvm::createStringError(
            llvm::inconvertibleErrorCode(),
            "Invalid parity (must be no, even, odd, mark or space): %s",
            x.str().c_str());
    } else if (x.consume_front("parity-check=")) {
      serial_options.ParityCheck =
          llvm::StringSwitch<std::optional<Terminal::ParityCheck>>(x)
              .Case("no", Terminal::ParityCheck::No)
              .Case("replace", Terminal::ParityCheck::ReplaceWithNUL)
              .Case("ignore", Terminal::ParityCheck::Ignore)
              // "mark" mode is not currently supported as it requires special
              // input processing
              // .Case("mark", Terminal::ParityCheck::Mark)
              .Default(std::nullopt);
      if (!serial_options.ParityCheck)
        return llvm::createStringError(
            llvm::inconvertibleErrorCode(),
            "Invalid parity-check (must be no, replace, ignore or mark): %s",
            x.str().c_str());
    } else if (x.consume_front("stop-bits=")) {
      unsigned int stop_bits;
      if (!llvm::to_integer(x, stop_bits, 10) ||
          (stop_bits != 1 && stop_bits != 2))
        return llvm::createStringError(
            llvm::inconvertibleErrorCode(),
            "Invalid stop bit number (must be 1 or 2): %s", x.str().c_str());
      serial_options.StopBits = stop_bits;
    } else
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "Unknown parameter: %s", x.str().c_str());
  }
  return serial_options;
}

llvm::Expected<std::unique_ptr<SerialPort>>
SerialPort::Create(int fd, OpenOptions options, Options serial_options,
                   bool transfer_ownership) {
  std::unique_ptr<SerialPort> out{
      new SerialPort(fd, options, serial_options, transfer_ownership)};

  if (!out->GetIsInteractive())
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "the specified file is not a teletype");

  Terminal term{fd};
  if (llvm::Error error = term.SetRaw())
    return std::move(error);
  if (serial_options.BaudRate) {
    if (llvm::Error error = term.SetBaudRate(*serial_options.BaudRate))
      return std::move(error);
  }
  if (serial_options.Parity) {
    if (llvm::Error error = term.SetParity(*serial_options.Parity))
      return std::move(error);
  }
  if (serial_options.ParityCheck) {
    if (llvm::Error error = term.SetParityCheck(*serial_options.ParityCheck))
      return std::move(error);
  }
  if (serial_options.StopBits) {
    if (llvm::Error error = term.SetStopBits(*serial_options.StopBits))
      return std::move(error);
  }

  return std::move(out);
}

SerialPort::SerialPort(int fd, OpenOptions options,
                       SerialPort::Options serial_options,
                       bool transfer_ownership)
    : NativeFile(fd, options, transfer_ownership), m_state(fd) {}

Status SerialPort::Close() {
  m_state.Restore();
  return NativeFile::Close();
}

char File::ID = 0;
char NativeFileBase::ID = 0;
char SerialPort::ID = 0;
