//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Implementation of a platform independent file data structure.
///
//===----------------------------------------------------------------------===//

#include "file.h"

#include "hdr/errno_macros.h"
#include "hdr/func/realloc.h"
#include "hdr/stdio_macros.h"
#include "hdr/types/off_t.h"
#include "hdr/wchar_macros.h"
#include "src/__support/CPP/new.h"
#include "src/__support/CPP/span.h"
#include "src/__support/alloc-checker.h"
#include "src/__support/error_or.h"
#include "src/__support/macros/config.h"
#include "src/__support/wchar/character_converter.h"
#include "src/__support/wchar/wcrtomb.h"
#include "src/string/memory_utils/inline_memcpy.h"

namespace LIBC_NAMESPACE_DECL {
File *File::list_all = nullptr;
Mutex File::list_lock(/*timed=*/false, /*recursive=*/false, /*robust=*/false,
                      /*pshared=*/false);

// Adds a file to the global list of all open files.
void File::add_file(File *f) {
  File::list_lock.lock();
  f->next = File::list_all;
  f->prev = nullptr;
  if (File::list_all != nullptr)
    File::list_all->prev = f;
  File::list_all = f;
  File::list_lock.unlock();
}

// Removes a file from the global list of all open files.
void File::remove_file(File *f) {
  File::list_lock.lock();
  if (f->prev != nullptr)
    f->prev->next = f->next;
  if (f->next != nullptr)
    f->next->prev = f->prev;
  if (File::list_all == f)
    File::list_all = f->next;
  f->prev = nullptr;
  f->next = nullptr;
  File::list_lock.unlock();
}

File *File::get_first_file() { return File::list_all; }
void File::lock_list() { File::list_lock.lock(); }
void File::unlock_list() { File::list_lock.unlock(); }

FileIOResult File::write_unlocked(const void *data, size_t len) {
  switch (orientation) {
  case Orientation::WIDE:
    err = true;
    return {0, EINVAL};
  case Orientation::UNORIENTED:
    orientation = Orientation::BYTE;
    break;
  case Orientation::BYTE:
    break;
  }
  return write_unlocked_impl(data, len);
}

FileIOResult File::write_unlocked_impl(const void *data, size_t len) {
  if (!write_allowed()) {
    err = true;
    return {0, EBADF};
  }

  prev_op = FileOp::WRITE;

  if (bufmode == _IONBF) { // unbuffered.
    size_t ret_val =
        write_unlocked_nbf(static_cast<const uint8_t *>(data), len);
    flush_unlocked();
    return ret_val;
  }
  if (bufmode == _IOFBF) // fully buffered
    return write_unlocked_fbf(static_cast<const uint8_t *>(data), len);
  return write_unlocked_lbf(static_cast<const uint8_t *>(data),
                            len); // line buffered
}

FileIOResult File::write_unlocked_nbf(const uint8_t *data, size_t len) {
  if (pos > 0) { // If the buffer is not empty
    // Flush the buffer
    const size_t write_size = pos;
    FileIOResult write_result = platform_write(this, buf, write_size);
    pos = 0; // Buffer is now empty so reset pos to the beginning.
    // If less bytes were written than expected, then an error occurred.
    if (write_result < write_size) {
      err = true;
      // No bytes from data were written, so return 0.
      return {0, write_result.error};
    }
  }

  FileIOResult write_result = platform_write(this, data, len);
  if (write_result < len)
    err = true;
  return write_result;
}

FileIOResult File::write_unlocked_fbf(const uint8_t *data, size_t len) {
  const size_t init_pos = pos;
  const size_t bufspace = bufsize - pos;

  // If data is too large to be buffered at all, then just write it unbuffered.
  if (len > bufspace + bufsize)
    return write_unlocked_nbf(data, len);

  // we split |data| (conceptually) using the split point. Then we handle the
  // two pieces separately.
  const size_t split_point = len < bufspace ? len : bufspace;

  // The primary piece is the piece of |data| we want to write to the buffer
  // before flushing. It will always fit into the buffer, since the split point
  // is defined as being min(len, bufspace), and it will always exist if len is
  // non-zero.
  cpp::span<const uint8_t> primary(data, split_point);

  // The second piece is the remainder of |data|. It is written to the buffer if
  // it fits, or written directly to the output if it doesn't. If the primary
  // piece fits entirely in the buffer, the remainder may be nothing.
  cpp::span<const uint8_t> remainder(
      static_cast<const uint8_t *>(data) + split_point, len - split_point);

  cpp::span<uint8_t> bufref(static_cast<uint8_t *>(buf), bufsize);

  // Copy the first piece into the buffer.
  inline_memcpy(bufref.data() + pos, primary.data(), primary.size());
  pos += primary.size();

  // If there is no remainder, we can return early, since the first piece has
  // fit completely into the buffer.
  if (remainder.size() == 0)
    return len;

  // We need to flush the buffer now, since there is still data and the buffer
  // is full.
  const size_t write_size = pos;

  FileIOResult buf_result = platform_write(this, buf, write_size);
  size_t bytes_written = buf_result.value;

  pos = 0; // Buffer is now empty so reset pos to the beginning.
  // If less bytes were written than expected, then an error occurred. Return
  // the number of bytes that have been written from |data|.
  if (buf_result.has_error() || bytes_written < write_size) {
    err = true;
    return {bytes_written <= init_pos ? 0 : bytes_written - init_pos,
            buf_result.error};
  }

  // The second piece is handled basically the same as the first, although we
  // know that if the second piece has data in it then the buffer has been
  // flushed, meaning that pos is always 0.
  if (remainder.size() < bufsize) {
    inline_memcpy(bufref.data(), remainder.data(), remainder.size());
    pos = remainder.size();
  } else {

    FileIOResult result =
        platform_write(this, remainder.data(), remainder.size());
    bytes_written = result.value;

    // If less bytes were written than expected, then an error occurred. Return
    // the number of bytes that have been written from |data|.
    if (result.has_error() || bytes_written < remainder.size()) {
      err = true;
      return {primary.size() + bytes_written, result.error};
    }
  }

  return len;
}

FileIOResult File::write_unlocked_lbf(const uint8_t *data, size_t len) {
  constexpr uint8_t NEWLINE_CHAR = '\n';
  size_t last_newline = len;
  for (size_t i = len; i >= 1; --i) {
    if (data[i - 1] == NEWLINE_CHAR) {
      last_newline = i - 1;
      break;
    }
  }

  // If there is no newline, treat this as fully buffered.
  if (last_newline == len) {
    return write_unlocked_fbf(data, len);
  }

  // we split |data| (conceptually) using the split point. Then we handle the
  // two pieces separately.
  const size_t split_point = last_newline + 1;

  // The primary piece is everything in |data| up to the newline. It's written
  // unbuffered to the output.
  cpp::span<const uint8_t> primary(data, split_point);

  // The second piece is the remainder of |data|. It is written fully buffered,
  // meaning it may stay in the buffer if it fits.
  cpp::span<const uint8_t> remainder(
      static_cast<const uint8_t *>(data) + split_point, len - split_point);

  size_t written = 0;

  written = write_unlocked_nbf(primary.data(), primary.size());
  if (written < primary.size()) {
    err = true;
    return written;
  }

  flush_unlocked();

  written += write_unlocked_fbf(remainder.data(), remainder.size());
  if (written < len) {
    err = true;
    return written;
  }

  return len;
}

FileIOResult File::read_unlocked(void *data, size_t len) {
  switch (orientation) {
  case Orientation::WIDE:
    err = true;
    return {0, EINVAL};
  case Orientation::UNORIENTED:
    orientation = Orientation::BYTE;
    break;
  case Orientation::BYTE:
    break;
  }
  return read_unlocked_impl(data, len);
}

FileIOResult File::read_unlocked_impl(void *data, size_t len) {
  if (!read_allowed()) {
    err = true;
    return {0, EBADF};
  }

  prev_op = FileOp::READ;

  if (bufmode == _IONBF) { // unbuffered.
    return read_unlocked_nbf(static_cast<uint8_t *>(data), len);
  } else if (bufmode == _IOFBF) { // fully buffered
    return read_unlocked_fbf(static_cast<uint8_t *>(data), len);
  } else /*if (bufmode == _IOLBF) */ { // line buffered
    // There is no line buffered mode for read. Use fully buffered instead.
    return read_unlocked_fbf(static_cast<uint8_t *>(data), len);
  }
}

size_t File::copy_data_from_buf(uint8_t *data, size_t len) {
  cpp::span<uint8_t> bufref(static_cast<uint8_t *>(buf), bufsize);
  cpp::span<uint8_t> dataref(static_cast<uint8_t *>(data), len);

  // Because read_limit is always greater than equal to pos,
  // available_data is never a wrapped around value.
  size_t available_data = read_limit - pos;
  if (len <= available_data) {
    inline_memcpy(dataref.data(), bufref.data() + pos, len);
    pos += len;
    return len;
  }

  // Copy all of the available data.
  inline_memcpy(dataref.data(), bufref.data() + pos, available_data);
  read_limit = pos = 0; // Reset the pointers.

  return available_data;
}

FileIOResult File::read_unlocked_fbf(uint8_t *data, size_t len) {
  // Read data from the buffer first.
  size_t available_data = copy_data_from_buf(data, len);
  if (available_data == len)
    return available_data;

  // Update the dataref to reflect that fact that we have already
  // copied |available_data| into |data|.
  size_t to_fetch = len - available_data;
  cpp::span<uint8_t> dataref(static_cast<uint8_t *>(data) + available_data,
                             to_fetch);

  if (to_fetch > bufsize) {
    FileIOResult result = platform_read(this, dataref.data(), to_fetch);
    size_t fetched_size = result.value;
    if (result.has_error() || fetched_size < to_fetch) {
      if (!result.has_error())
        eof = true;
      else
        err = true;
      return {available_data + fetched_size, result.error};
    }
    return len;
  }

  // Fetch and buffer another buffer worth of data.
  FileIOResult result = platform_read(this, buf, bufsize);
  size_t fetched_size = result.value;
  read_limit += fetched_size;
  size_t transfer_size = fetched_size >= to_fetch ? to_fetch : fetched_size;
  inline_memcpy(dataref.data(), buf, transfer_size);
  pos += transfer_size;
  if (result.has_error() || fetched_size < to_fetch) {
    if (!result.has_error())
      eof = true;
    else
      err = true;
  }
  return {transfer_size + available_data, result.error};
}

FileIOResult File::read_unlocked_nbf(uint8_t *data, size_t len) {
  // Check whether there is a character in the ungetc buffer.
  size_t available_data = copy_data_from_buf(data, len);
  if (available_data == len)
    return available_data;

  // Directly copy the data into |data|.
  cpp::span<uint8_t> dataref(static_cast<uint8_t *>(data) + available_data,
                             len - available_data);
  FileIOResult result = platform_read(this, dataref.data(), dataref.size());

  if (result.has_error() || result < dataref.size()) {
    if (!result.has_error())
      eof = true;
    else
      err = true;
  }
  return {result + available_data, result.error};
}

int File::ungetc_unlocked(int c) {
  // There is no meaning to unget if:
  // 1. You are trying to push back EOF.
  // 2. Read operations are not allowed on this file.
  // 3. The previous operation was a write operation.
  if (c == EOF || !read_allowed() || (prev_op == FileOp::WRITE))
    return EOF;

  switch (orientation) {
  case Orientation::WIDE:
    err = true;
    return EOF;
  case Orientation::UNORIENTED:
    orientation = Orientation::BYTE;
    break;
  case Orientation::BYTE:
    break;
  }

  cpp::span<uint8_t> bufref(static_cast<uint8_t *>(buf), bufsize);
  if (read_limit == 0) {
    // If |read_limit| is zero, it can mean three things:
    //   a. This file was just created.
    //   b. The previous operation was a seek operation.
    //   c. The previous operation was a read operation which emptied
    //      the buffer.
    // For all the above cases, we simply write |c| at the beginning
    // of the buffer and bump |read_limit|. Note that |pos| will also
    // be zero in this case, so we don't need to adjust it.
    bufref[0] = static_cast<unsigned char>(c);
    ++read_limit;
  } else {
    // If |read_limit| is non-zero, it means that there is data in the buffer
    // from a previous read operation. Which would also mean that |pos| is not
    // zero. So, we decrement |pos| and write |c| in to the buffer at the new
    // |pos|. If too many ungetc operations are performed without reads, it
    // can lead to (pos == 0 but read_limit != 0). We will just error out in
    // such a case.
    if (pos == 0)
      return EOF;
    --pos;
    bufref[pos] = static_cast<unsigned char>(c);
  }

  eof = false; // There is atleast one character that can be read now.
  err = false; // This operation was a success.
  return c;
}

ErrorOr<int> File::seek(off_t offset, int whence) {
  FileLock lock(this);
  if (prev_op == FileOp::WRITE && pos > 0) {

    FileIOResult buf_result = platform_write(this, buf, pos);
    if (buf_result.has_error() || buf_result.value < pos) {
      err = true;
      return Error(buf_result.error);
    }
  } else if (prev_op == FileOp::READ && whence == SEEK_CUR) {
    // More data could have been read out from the platform file than was
    // required. So, we have to adjust the offset we pass to platform seek
    // function. Note that read_limit >= pos is always true.
    offset -= (read_limit - pos);
  }
  auto result = platform_seek(this, offset, whence);
  if (!result.has_value())
    return Error(result.error());

  pos = read_limit = 0;
  prev_op = FileOp::SEEK;
  // Reset the eof flag as a seek might move the file position to some place
  // readable.
  eof = false;
  if (orientation == Orientation::WIDE ||
      orientation == Orientation::UNORIENTED)
    mbstate = internal::mbstate();

  return 0;
}

ErrorOr<off_t> File::tell() {
  FileLock lock(this);
  auto seek_target = eof ? SEEK_END : SEEK_CUR;
  auto result = platform_seek(this, 0, seek_target);
  if (!result.has_value() || result.value() < 0)
    return Error(result.error());
  off_t platform_offset = result.value();
  if (prev_op == FileOp::READ)
    return platform_offset - (read_limit - pos);
  if (prev_op == FileOp::WRITE)
    return platform_offset + pos;
  return platform_offset;
}

int File::flush_unlocked() {
  if (prev_op == FileOp::WRITE && pos > 0) {
    FileIOResult buf_result = platform_write(this, buf, pos);
    if (buf_result.has_error() || buf_result.value < pos) {
      err = true;
      return buf_result.error;
    }
    pos = 0;
  } else if (prev_op == FileOp::READ) {
    if (read_limit > pos) {
      if (!platform_seek(this, -static_cast<off_t>(read_limit - pos), SEEK_CUR)
               .has_value()) {
        // We ignore seek errors for non-seekable files (like pipes) as per
        // POSIX.
      }
    }
    pos = read_limit = 0;
  }
  return 0;
}

// Does the following:
// 1. If in write mode, Write out any data present in the buffer.
// 2. Call platform_close.
// platform_close is expected to cleanup the complete file object.
int File::close() {
  {
    FileLock lock(this);
    if (prev_op == FileOp::WRITE && pos > 0) {
      auto buf_result = platform_write(this, buf, pos);
      if (buf_result.has_error() || buf_result.value < pos) {
        err = true;
        return buf_result.error;
      }
    }
  }

  // If we own the buffer, delete it before calling the platform close
  // implementation. The platform close should not need to access the buffer
  // and we need to clean it up before the entire structure is removed.
  if (own_buf)
    delete buf;

  // Platform close is expected to cleanup the file data structure which
  // includes the file mutex. Hence, we call platform_close after releasing
  // the file lock. Another thread doing file operations while a thread is
  // closing the file is undefined behavior as per POSIX.
  return platform_close(this);
}

int File::set_buffer(void *buffer, size_t size, int buffer_mode) {
  // We do not need to lock the file as this method should be called before
  // other operations are performed on the file.
  if (buffer != nullptr && size == 0)
    return EINVAL;

  switch (buffer_mode) {
  case _IOFBF:
  case _IOLBF:
  case _IONBF:
    break;
  default:
    return EINVAL;
  }

  if (buffer == nullptr && size != 0 && buffer_mode != _IONBF) {
    // We exclude the case of buffer_mode == _IONBF in this branch
    // because we don't need to allocate buffer in such a case.
    if (own_buf) {
      // This is one of the places where a C allocation function is used
      // as C++ does not have an equivalent of realloc.
      buf = reinterpret_cast<uint8_t *>(realloc(buf, size));
      if (buf == nullptr)
        return ENOMEM;
    } else {
      AllocChecker ac;
      buf = new (ac) uint8_t[size];
      if (!ac)
        return ENOMEM;
      own_buf = true;
    }
    bufsize = size;
    // TODO: Handle allocation failures.
  } else {
    if (own_buf)
      delete buf;
    if (buffer_mode != _IONBF) {
      buf = static_cast<uint8_t *>(buffer);
      bufsize = size;
    } else {
      // We don't need any buffer.
      buf = nullptr;
      bufsize = 0;
    }
    own_buf = false;
  }
  bufmode = buffer_mode;
  adjust_buf();
  return 0;
}

FileIOResult File::write_unlocked(const wchar_t *ws, size_t len) {
  switch (orientation) {
  case Orientation::BYTE:
    err = true;
    return {0, EINVAL};
  case Orientation::UNORIENTED:
    orientation = Orientation::WIDE;
    break;
  case Orientation::WIDE:
    break;
  }

  size_t written = 0;
  for (size_t i = 0; i < len; ++i) {
    internal::CharacterConverter cr(&mbstate);
    int push_err = cr.push(static_cast<char32_t>(ws[i]));
    if (push_err != 0) {
      err = true;
      return {written, push_err};
    }
    // buffer the whole wchar to save on calls to write.
    char buffer[4];
    size_t char_size = 0;
    while (!cr.isEmpty()) {
      auto pop_res = cr.pop<char8_t>();
      if (!pop_res.has_value()) {
        err = true;
        return {written, pop_res.error()};
      }
      char8_t byte = pop_res.value();
      buffer[char_size] = byte;
      ++char_size;
    }
    auto write_res = write_unlocked_impl(buffer, char_size);
    if (write_res.has_error())
      return {written, write_res.error};
    if (write_res.value < char_size) {
      err = true;
      return {written, EIO};
    }
    ++written;
  }
  return {written, 0};
}

FileIOResult File::read_unlocked(wchar_t *ws, size_t len) {
  switch (orientation) {
  case Orientation::BYTE:
    err = true;
    return {0, EINVAL};
  case Orientation::UNORIENTED:
    orientation = Orientation::WIDE;
    break;
  case Orientation::WIDE:
    break;
  }

  size_t read_count = 0;
  for (size_t i = 0; i < len; ++i) {
    internal::CharacterConverter cr(&mbstate);
    while (!cr.isFull()) {
      uint8_t byte;
      auto read_res = read_unlocked_impl(&byte, 1);
      if (read_res.has_error())
        return {read_count, read_res.error};
      if (read_res.value == 0) { // EOF
        if (cr.isEmpty())
          return {read_count, 0};
        err = true;
        return {read_count, EILSEQ}; // Incomplete character at EOF
      }
      int push_err = cr.push(static_cast<char8_t>(byte));
      if (push_err != 0) {
        err = true;
        return {read_count, push_err};
      }
    }
    auto pop_res = cr.pop<char32_t>();
    if (!pop_res.has_value()) {
      err = true;
      return {read_count, pop_res.error()};
    }
    ws[i] = static_cast<wchar_t>(pop_res.value());
    ++read_count;
  }
  return {read_count, 0};
}

ErrorOr<wint_t> File::ungetwc_unlocked(wint_t wc) {
  // There is no meaning to unget if:
  // 1. You are trying to push back EOF.
  // 2. Read operations are not allowed on this file.
  // 3. The previous operation was a write operation.
  if (wc == WEOF || !read_allowed() || (prev_op == FileOp::WRITE))
    return WEOF;
  switch (orientation) {
  case Orientation::BYTE:
    err = true;
    return WEOF;
  case Orientation::UNORIENTED:
    orientation = Orientation::WIDE;
    break;
  case Orientation::WIDE:
    break;
  }

  char mb_buf[4];
  auto result = internal::wcrtomb(mb_buf, static_cast<wchar_t>(wc), &mbstate);
  if (!result.has_value())
    return Error(result.error());

  size_t n = result.value();

  if (read_limit == 0) {
    if (n > bufsize)
      return WEOF;

    for (size_t i = 0; i < n; ++i)
      buf[i] = static_cast<uint8_t>(mb_buf[i]);

    read_limit = n;
    pos = 0;
  } else {
    if (pos < n)
      return WEOF;
    pos -= n;
    for (size_t i = 0; i < n; ++i)
      buf[pos + i] = static_cast<uint8_t>(mb_buf[i]);
  }
  eof = false;
  err = false;
  return wc;
}

} // namespace LIBC_NAMESPACE_DECL
