// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/filesystem/file_impl.h"

#include <stddef.h>
#include <stdint.h>
#include <limits>
#include <memory>
#include <utility>

#include "base/files/file_path.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "build/build_config.h"
#include "components/filesystem/lock_table.h"
#include "components/filesystem/shared_temp_dir.h"
#include "components/filesystem/util.h"
#include "mojo/public/cpp/bindings/strong_binding.h"

static_assert(sizeof(off_t) <= sizeof(int64_t), "off_t too big");
static_assert(sizeof(size_t) >= sizeof(uint32_t), "size_t too small");

using base::Time;

namespace filesystem {
namespace {

const size_t kMaxReadSize = 1 * 1024 * 1024;  // 1 MB.

}  // namespace

FileImpl::FileImpl(const base::FilePath& path,
                   uint32_t flags,
                   scoped_refptr<SharedTempDir> temp_dir,
                   scoped_refptr<LockTable> lock_table)
    : file_(path, flags),
      path_(path),
      temp_dir_(std::move(temp_dir)),
      lock_table_(std::move(lock_table)) {
  DCHECK(file_.IsValid());
}

FileImpl::FileImpl(const base::FilePath& path,
                   base::File file,
                   scoped_refptr<SharedTempDir> temp_dir,
                   scoped_refptr<LockTable> lock_table)
    : file_(std::move(file)),
      path_(path),
      temp_dir_(std::move(temp_dir)),
      lock_table_(std::move(lock_table)) {
  DCHECK(file_.IsValid());
}

FileImpl::~FileImpl() {
  if (file_.IsValid())
    lock_table_->RemoveFromLockTable(path_);
}

bool FileImpl::IsValid() const {
  return file_.IsValid();
}

#if !defined(OS_FUCHSIA)
base::File::Error FileImpl::RawLockFile() {
  return file_.Lock();
}

base::File::Error FileImpl::RawUnlockFile() {
  return file_.Unlock();
}
#endif  // !OS_FUCHSIA

void FileImpl::Close(CloseCallback callback) {
  if (!file_.IsValid()) {
    std::move(callback).Run(GetError(file_));
    return;
  }

  lock_table_->RemoveFromLockTable(path_);
  file_.Close();
  std::move(callback).Run(mojom::FileError::OK);
}

// TODO(vtl): Move the implementation to a thread pool.
void FileImpl::Read(uint32_t num_bytes_to_read,
                    int64_t offset,
                    mojom::Whence whence,
                    ReadCallback callback) {
  if (!file_.IsValid()) {
    std::move(callback).Run(GetError(file_), base::nullopt);
    return;
  }
  if (num_bytes_to_read > kMaxReadSize) {
    std::move(callback).Run(mojom::FileError::INVALID_OPERATION, base::nullopt);
    return;
  }
  mojom::FileError error = IsOffsetValid(offset);
  if (error != mojom::FileError::OK) {
    std::move(callback).Run(error, base::nullopt);
    return;
  }
  error = IsWhenceValid(whence);
  if (error != mojom::FileError::OK) {
    std::move(callback).Run(error, base::nullopt);
    return;
  }

  if (file_.Seek(static_cast<base::File::Whence>(whence), offset) == -1) {
    std::move(callback).Run(mojom::FileError::FAILED, base::nullopt);
    return;
  }

  std::vector<uint8_t> bytes_read(num_bytes_to_read);
  int num_bytes_read = file_.ReadAtCurrentPos(
      reinterpret_cast<char*>(&bytes_read.front()), num_bytes_to_read);
  if (num_bytes_read < 0) {
    std::move(callback).Run(mojom::FileError::FAILED, base::nullopt);
    return;
  }

  DCHECK_LE(static_cast<size_t>(num_bytes_read), num_bytes_to_read);
  bytes_read.resize(static_cast<size_t>(num_bytes_read));
  std::move(callback).Run(mojom::FileError::OK, std::move(bytes_read));
}

// TODO(vtl): Move the implementation to a thread pool.
void FileImpl::Write(const std::vector<uint8_t>& bytes_to_write,
                     int64_t offset,
                     mojom::Whence whence,
                     WriteCallback callback) {
  if (!file_.IsValid()) {
    std::move(callback).Run(GetError(file_), 0);
    return;
  }
  // Who knows what |write()| would return if the size is that big (and it
  // actually wrote that much).
  if (bytes_to_write.size() >
#if defined(OS_WIN)
      static_cast<size_t>(std::numeric_limits<int>::max())) {
#else
      static_cast<size_t>(std::numeric_limits<ssize_t>::max())) {
#endif
    std::move(callback).Run(mojom::FileError::INVALID_OPERATION, 0);
    return;
  }
  mojom::FileError error = IsOffsetValid(offset);
  if (error != mojom::FileError::OK) {
    std::move(callback).Run(error, 0);
    return;
  }
  error = IsWhenceValid(whence);
  if (error != mojom::FileError::OK) {
    std::move(callback).Run(error, 0);
    return;
  }

  if (file_.Seek(static_cast<base::File::Whence>(whence), offset) == -1) {
    std::move(callback).Run(mojom::FileError::FAILED, 0);
    return;
  }

  const char* buf = (bytes_to_write.size() > 0)
                        ? reinterpret_cast<const char*>(&bytes_to_write.front())
                        : nullptr;
  int num_bytes_written = file_.WriteAtCurrentPos(
      buf, static_cast<int>(bytes_to_write.size()));
  if (num_bytes_written < 0) {
    std::move(callback).Run(mojom::FileError::FAILED, 0);
    return;
  }

  DCHECK_LE(static_cast<size_t>(num_bytes_written),
            std::numeric_limits<uint32_t>::max());
  std::move(callback).Run(mojom::FileError::OK,
                          static_cast<uint32_t>(num_bytes_written));
}

void FileImpl::Tell(TellCallback callback) {
  Seek(0, mojom::Whence::FROM_CURRENT, std::move(callback));
}

void FileImpl::Seek(int64_t offset,
                    mojom::Whence whence,
                    SeekCallback callback) {
  if (!file_.IsValid()) {
    std::move(callback).Run(GetError(file_), 0);
    return;
  }
  mojom::FileError error = IsOffsetValid(offset);
  if (error != mojom::FileError::OK) {
    std::move(callback).Run(error, 0);
    return;
  }
  error = IsWhenceValid(whence);
  if (error != mojom::FileError::OK) {
    std::move(callback).Run(error, 0);
    return;
  }

  int64_t position =
      file_.Seek(static_cast<base::File::Whence>(whence), offset);
  if (position < 0) {
    std::move(callback).Run(mojom::FileError::FAILED, 0);
    return;
  }

  std::move(callback).Run(mojom::FileError::OK, static_cast<int64_t>(position));
}

void FileImpl::Stat(StatCallback callback) {
  if (!file_.IsValid()) {
    std::move(callback).Run(GetError(file_), nullptr);
    return;
  }

  base::File::Info info;
  if (!file_.GetInfo(&info)) {
    std::move(callback).Run(mojom::FileError::FAILED, nullptr);
    return;
  }

  std::move(callback).Run(mojom::FileError::OK, MakeFileInformation(info));
}

void FileImpl::Truncate(int64_t size, TruncateCallback callback) {
  if (!file_.IsValid()) {
    std::move(callback).Run(GetError(file_));
    return;
  }
  if (size < 0) {
    std::move(callback).Run(mojom::FileError::INVALID_OPERATION);
    return;
  }
  mojom::FileError error = IsOffsetValid(size);
  if (error != mojom::FileError::OK) {
    std::move(callback).Run(error);
    return;
  }

  if (!file_.SetLength(size)) {
    std::move(callback).Run(mojom::FileError::NOT_FOUND);
    return;
  }

  std::move(callback).Run(mojom::FileError::OK);
}

void FileImpl::Touch(mojom::TimespecOrNowPtr atime,
                     mojom::TimespecOrNowPtr mtime,
                     TouchCallback callback) {
  if (!file_.IsValid()) {
    std::move(callback).Run(GetError(file_));
    return;
  }

  base::Time base_atime = Time::Now();
  if (!atime) {
    base::File::Info info;
    if (!file_.GetInfo(&info)) {
      std::move(callback).Run(mojom::FileError::FAILED);
      return;
    }

    base_atime = info.last_accessed;
  } else if (!atime->now) {
    base_atime = Time::FromDoubleT(atime->seconds);
  }

  base::Time base_mtime = Time::Now();
  if (!mtime) {
    base::File::Info info;
    if (!file_.GetInfo(&info)) {
      std::move(callback).Run(mojom::FileError::FAILED);
      return;
    }

    base_mtime = info.last_modified;
  } else if (!mtime->now) {
    base_mtime = Time::FromDoubleT(mtime->seconds);
  }

  file_.SetTimes(base_atime, base_mtime);
  std::move(callback).Run(mojom::FileError::OK);
}

void FileImpl::Dup(mojom::FileRequest file, DupCallback callback) {
  if (!file_.IsValid()) {
    std::move(callback).Run(GetError(file_));
    return;
  }

  base::File new_file = file_.Duplicate();
  if (!new_file.IsValid()) {
    std::move(callback).Run(GetError(new_file));
    return;
  }

  if (file.is_pending()) {
    mojo::MakeStrongBinding(
        std::make_unique<FileImpl>(path_, std::move(new_file), temp_dir_,
                                   lock_table_),
        std::move(file));
  }
  std::move(callback).Run(mojom::FileError::OK);
}

void FileImpl::Flush(FlushCallback callback) {
  if (!file_.IsValid()) {
    std::move(callback).Run(GetError(file_));
    return;
  }

  bool ret = file_.Flush();
  std::move(callback).Run(ret ? mojom::FileError::OK
                              : mojom::FileError::FAILED);
}

void FileImpl::Lock(LockCallback callback) {
  std::move(callback).Run(
      static_cast<filesystem::mojom::FileError>(lock_table_->LockFile(this)));
}

void FileImpl::Unlock(UnlockCallback callback) {
  std::move(callback).Run(
      static_cast<filesystem::mojom::FileError>(lock_table_->UnlockFile(this)));
}

void FileImpl::AsHandle(AsHandleCallback callback) {
  if (!file_.IsValid()) {
    std::move(callback).Run(GetError(file_), base::File());
    return;
  }

  base::File new_file = file_.Duplicate();
  if (!new_file.IsValid()) {
    std::move(callback).Run(GetError(new_file), base::File());
    return;
  }

  base::File::Info info;
  if (!new_file.GetInfo(&info)) {
    std::move(callback).Run(mojom::FileError::FAILED, base::File());
    return;
  }

  // Perform one additional check right before we send the file's file
  // descriptor over mojo. This is theoretically redundant, but given that
  // passing a file descriptor to a directory is a sandbox escape on Windows,
  // we should be absolutely paranoid.
  if (info.is_directory) {
    std::move(callback).Run(mojom::FileError::NOT_A_FILE, base::File());
    return;
  }

  std::move(callback).Run(mojom::FileError::OK, std::move(new_file));
}

}  // namespace filesystem
