// 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 <utility>

#include "base/files/file_path.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/memory/ptr_util.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();
}

base::File::Error FileImpl::RawLockFile() {
  return file_.Lock();
}

base::File::Error FileImpl::RawUnlockFile() {
  return file_.Unlock();
}

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

  lock_table_->RemoveFromLockTable(path_);
  file_.Close();
  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,
                    const ReadCallback& callback) {
  if (!file_.IsValid()) {
    callback.Run(GetError(file_), base::nullopt);
    return;
  }
  if (num_bytes_to_read > kMaxReadSize) {
    callback.Run(mojom::FileError::INVALID_OPERATION, base::nullopt);
    return;
  }
  mojom::FileError error = IsOffsetValid(offset);
  if (error != mojom::FileError::OK) {
    callback.Run(error, base::nullopt);
    return;
  }
  error = IsWhenceValid(whence);
  if (error != mojom::FileError::OK) {
    callback.Run(error, base::nullopt);
    return;
  }

  if (file_.Seek(static_cast<base::File::Whence>(whence), offset) == -1) {
    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) {
    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));
  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,
                     const WriteCallback& callback) {
  if (!file_.IsValid()) {
    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
    callback.Run(mojom::FileError::INVALID_OPERATION, 0);
    return;
  }
  mojom::FileError error = IsOffsetValid(offset);
  if (error != mojom::FileError::OK) {
    callback.Run(error, 0);
    return;
  }
  error = IsWhenceValid(whence);
  if (error != mojom::FileError::OK) {
    callback.Run(error, 0);
    return;
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

  base::Time base_atime = Time::Now();
  if (!atime) {
    base::File::Info info;
    if (!file_.GetInfo(&info)) {
      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)) {
      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);
  callback.Run(mojom::FileError::OK);
}

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

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

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

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

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

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

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

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

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

  base::File::Info info;
  if (!new_file.GetInfo(&info)) {
    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) {
    callback.Run(mojom::FileError::NOT_A_FILE, base::File());
    return;
  }

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

}  // namespace filesystem
