//===--- Implementation of the Linux specialization of File ---------------===//
//
// 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 "file.h"
#include "file_flags.h"
#include "hdr/stdio_macros.h"
#include "hdr/sys_stat_macros.h" // For S_IS*, S_IF*, and S_IR* flags.
#include "hdr/types/off_t.h"
#include "src/__support/CPP/new.h"
#include "src/__support/File/file.h"
#include "src/__support/File/file_mode.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/close.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/dup3.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/fcntl.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/lseek.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/open.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/read.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/write.h"
#include "src/__support/alloc-checker.h"
#include "src/__support/libc_errno.h" // For error macros
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {

FileIOResult linux_file_write(File *f, const void *data, size_t size) {
  auto *lf = reinterpret_cast<LinuxFile *>(f);
  auto ret = linux_syscalls::write(lf->get_fd(), data, size);
  if (!ret) {
    return {0, ret.error()};
  }
  return static_cast<size_t>(ret.value());
}

FileIOResult linux_file_read(File *f, void *buf, size_t size) {
  auto *lf = reinterpret_cast<LinuxFile *>(f);
  auto ret = linux_syscalls::read(lf->get_fd(), buf, size);
  if (!ret) {
    return {0, ret.error()};
  }
  return static_cast<size_t>(ret.value());
}

ErrorOr<off_t> linux_file_seek(File *f, off_t offset, int whence) {
  auto *lf = reinterpret_cast<LinuxFile *>(f);
  return linux_syscalls::lseek(lf->get_fd(), offset, whence);
}

int linux_file_close(File *f) {
  File::remove_file(f);
  auto *lf = reinterpret_cast<LinuxFile *>(f);
  int retval = 0;
  if (lf->get_fd() >= 0) {
    // Linux closes the file descriptor early in the syscall, so we assume it's
    // always closed after the call. That means we should also delete the
    // LinuxFile on error.
    auto result = linux_syscalls::close(lf->get_fd());
    if (!result)
      retval = result.error();
  } else {
    retval = EBADF;
  }
  delete lf;
  return retval;
}

static int map_c_mode_flags_to_linux_open_flags(const FileMode &file_mode) {
  int open_flags = 0;

  // handle access patterns i.e whether the file should be in
  // only read, write modes or both.
  if (file_mode.is_update())
    open_flags = LinuxFileFlags::READ_AND_WRITE;
  else if (file_mode.is_append() || file_mode.is_write())
    open_flags = LinuxFileFlags::WRITE_ONLY;
  else
    open_flags = LinuxFileFlags::READ_ONLY;

  // handle the behaviour of the file when accessed i.e should the file
  // be appended to or truncate when created.
  if (file_mode.is_append())
    open_flags |= LinuxFileFlags::CREATE_AND_APPEND;
  else if (file_mode.is_write())
    open_flags |= LinuxFileFlags::CREATE_OR_TRUNCATE;

  // Ignore 'x' for read modes: O_EXCL is only meaningful with O_CREAT here.
  if (file_mode.is_exclusive_create() &&
      (file_mode.is_write() || file_mode.is_append()))
    open_flags |= LinuxFileFlags::EXCLUSIVE_CREATE;

  if (file_mode.is_close_on_exec())
    open_flags |= LinuxFileFlags::CLOSE_ON_EXEC;

  return open_flags;
}

ErrorOr<File *> openfile(const char *path, const char *mode) {
  const FileMode file_mode(mode);

  if (!file_mode.is_valid()) {
    return Error(EINVAL);
  }
  int open_flags = map_c_mode_flags_to_linux_open_flags(file_mode);

  ErrorOr<int> fd =
      linux_syscalls::open(path, open_flags, LinuxFileFlags::OPEN_MODE);
  if (!fd)
    return Error(fd.error());

  uint8_t *buffer;
  {
    AllocChecker ac;
    buffer = new (ac) uint8_t[File::DEFAULT_BUFFER_SIZE];
    if (!ac)
      return Error(ENOMEM);
  }
  AllocChecker ac;
  auto *file = new (ac) LinuxFile(fd.value(), buffer, File::DEFAULT_BUFFER_SIZE,
                                  _IOFBF, true, file_mode);
  if (!ac)
    return Error(ENOMEM);
  File::add_file(file);
  return file;
}

static ErrorOr<int> set_close_on_exec(int fd) {
  auto flags = linux_syscalls::fcntl(fd, F_GETFD);
  if (!flags)
    return Error(flags.error());
  return linux_syscalls::fcntl(
      fd, F_SETFD, reinterpret_cast<void *>(flags.value() | FD_CLOEXEC));
}

ErrorOr<LinuxFile *> create_file_from_fd(int fd, const char *mode) {
  const FileMode file_mode(mode);

  if (!file_mode.is_valid()) {
    return Error(EINVAL);
  }

  auto result = linux_syscalls::fcntl(fd, F_GETFL);
  if (!result.has_value()) {
    return Error(EBADF);
  }
  int fd_flags = result.value();

  if ((LinuxFileFlags::is_file_descriptor_opened_in_read_only(fd_flags) &&
       file_mode.write_allowed()) ||
      (LinuxFileFlags::is_file_descriptor_opened_in_write_only(fd_flags) &&
       file_mode.read_allowed())) {
    return Error(EINVAL);
  }

  if (file_mode.is_close_on_exec()) {
    auto cloexec_result = set_close_on_exec(fd);
    if (!cloexec_result)
      return Error(cloexec_result.error());
  }

  bool do_seek = false;
  if (file_mode.is_append() &&
      !LinuxFileFlags::file_has_append_flag(fd_flags)) {
    do_seek = true;
    if (!linux_syscalls::fcntl(fd, F_SETFL,
                               reinterpret_cast<void *>(fd_flags | O_APPEND))
             .has_value()) {
      return Error(EBADF);
    }
  }

  uint8_t *buffer;
  {
    AllocChecker ac;
    buffer = new (ac) uint8_t[File::DEFAULT_BUFFER_SIZE];
    if (!ac) {
      return Error(ENOMEM);
    }
  }
  AllocChecker ac;
  auto *file = new (ac)
      LinuxFile(fd, buffer, File::DEFAULT_BUFFER_SIZE, _IOFBF, true, file_mode);
  if (!ac) {
    return Error(ENOMEM);
  }
  File::add_file(file);
  if (do_seek) {
    result = file->seek(0, SEEK_END);
    if (!result.has_value()) {
      File::remove_file(file);
      delete file;
      return Error(result.error());
    }
  }
  return file;
}

int LinuxFile::reopen_unlocked(const char *path, const char *mode) {
  flush_unlocked();

  const FileMode file_mode(mode);

  if (path != nullptr) {
    int old_fd = get_fd();

    if (!file_mode.is_valid()) {
      if (old_fd >= 0) {
        linux_syscalls::close(old_fd);
        set_fd(-1);
      }
      reset_stream_state_unlocked(file_mode);
      return EINVAL;
    }

    int open_flags = map_c_mode_flags_to_linux_open_flags(file_mode);

    // Prevent the temporary descriptor from being inherited across exec.
    if (old_fd >= 0)
      open_flags |= LinuxFileFlags::CLOSE_ON_EXEC;

    ErrorOr<int> new_fd =
        linux_syscalls::open(path, open_flags, LinuxFileFlags::OPEN_MODE);

    // If the new file fails to open, POSIX says we still have to close the old
    // file.
    if (!new_fd) {
      if (old_fd >= 0) {
        // POSIX: "Failure to close the file descriptor successfully shall be
        // ignored"
        linux_syscalls::close(old_fd);

        set_fd(-1);
      }
      reset_stream_state_unlocked(file_mode);
      return new_fd.error();
    }

    // Else the new file successfully opened, so we move it into the fd the old
    // file was using if the old fd exists.
    if (old_fd >= 0) {
      // Preserve close-on-exec atomically when replacing the old descriptor.
      int dup_flags =
          file_mode.is_close_on_exec() ? LinuxFileFlags::CLOSE_ON_EXEC : 0;
      auto dup_result = linux_syscalls::dup3(new_fd.value(), old_fd, dup_flags);
      if (!dup_result) {
        linux_syscalls::close(new_fd.value());
        reset_stream_state_unlocked(file_mode);
        return dup_result.error();
      }
      auto close_result = linux_syscalls::close(new_fd.value());
      if (!close_result) {
        reset_stream_state_unlocked(file_mode);
        return close_result.error();
      }
    } else {
      set_fd(new_fd.value());
    }

    reset_stream_state_unlocked(file_mode);
    return 0;
  }

  if (!file_mode.is_valid())
    return EINVAL;

  if (fd < 0)
    return EBADF;

  auto result = linux_syscalls::fcntl(fd, F_GETFL);
  if (!result.has_value())
    return EBADF;
  int fd_flags = result.value();

  if ((LinuxFileFlags::is_file_descriptor_opened_in_read_only(fd_flags) &&
       file_mode.write_allowed()) ||
      (LinuxFileFlags::is_file_descriptor_opened_in_write_only(fd_flags) &&
       file_mode.read_allowed())) {
    return EBADF;
  }

  bool do_seek = false;
  bool has_append_flag = LinuxFileFlags::file_has_append_flag(fd_flags);

  if (file_mode.is_append() && !has_append_flag) {
    if (!linux_syscalls::fcntl(fd, F_SETFL,
                               reinterpret_cast<void *>(fd_flags | O_APPEND))
             .has_value()) {
      return EBADF;
    }
    do_seek = true;
  } else if (!file_mode.is_append() && has_append_flag) {
    if (!linux_syscalls::fcntl(fd, F_SETFL,
                               reinterpret_cast<void *>(fd_flags & ~O_APPEND))
             .has_value()) {
      return EBADF;
    }
  }

  reset_stream_state_unlocked(file_mode);

  if (do_seek) {
    auto seek_result = linux_file_seek(this, 0, SEEK_END);
    if (!seek_result.has_value())
      return seek_result.error();
  }
  return 0;
}

int get_fileno(File *f) {
  auto *lf = reinterpret_cast<LinuxFile *>(f);
  return lf->get_fd();
}

int reopenfile(File *f, const char *path, const char *mode) {
  File::FileLock lock(f);
  return reopenfile_unlocked(f, path, mode);
}

int reopenfile_unlocked(File *f, const char *path, const char *mode) {
  auto *lf = reinterpret_cast<LinuxFile *>(f);
  return lf->reopen_unlocked(path, mode);
}

} // namespace LIBC_NAMESPACE_DECL
