// Copyright 2014 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 "base/files/file_proxy.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/file_util.h"
#include "base/files/file.h"
#include "base/location.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/task_runner.h"
#include "base/task_runner_util.h"

namespace {

void FileDeleter(base::File file) {
}

}  // namespace

namespace base {

class FileHelper {
 public:
   FileHelper(FileProxy* proxy, File file)
      : file_(file.Pass()),
        error_(File::FILE_ERROR_FAILED),
        task_runner_(proxy->task_runner()),
        proxy_(AsWeakPtr(proxy)) {
   }

   void PassFile() {
     if (proxy_)
       proxy_->SetFile(file_.Pass());
     else if (file_.IsValid())
       task_runner_->PostTask(FROM_HERE, Bind(&FileDeleter, Passed(&file_)));
   }

 protected:
  File file_;
  File::Error error_;

 private:
  scoped_refptr<TaskRunner> task_runner_;
  WeakPtr<FileProxy> proxy_;
  DISALLOW_COPY_AND_ASSIGN(FileHelper);
};

namespace {

class GenericFileHelper : public FileHelper {
 public:
  GenericFileHelper(FileProxy* proxy, File file)
      : FileHelper(proxy, file.Pass()) {
  }

  void Close() {
    file_.Close();
    error_ = File::FILE_OK;
  }

  void SetTimes(Time last_access_time, Time last_modified_time) {
    bool rv = file_.SetTimes(last_access_time, last_modified_time);
    error_ = rv ? File::FILE_OK : File::FILE_ERROR_FAILED;
  }

  void SetLength(int64 length) {
    if (file_.SetLength(length))
      error_ = File::FILE_OK;
  }

  void Flush() {
    if (file_.Flush())
      error_ = File::FILE_OK;
  }

  void Reply(const FileProxy::StatusCallback& callback) {
    PassFile();
    if (!callback.is_null())
      callback.Run(error_);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(GenericFileHelper);
};

class CreateOrOpenHelper : public FileHelper {
 public:
  CreateOrOpenHelper(FileProxy* proxy, File file)
      : FileHelper(proxy, file.Pass()) {
  }

  void RunWork(const FilePath& file_path, int file_flags) {
    file_.Initialize(file_path, file_flags);
    error_ = file_.IsValid() ? File::FILE_OK : file_.error_details();
  }

  void Reply(const FileProxy::StatusCallback& callback) {
    DCHECK(!callback.is_null());
    PassFile();
    callback.Run(error_);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(CreateOrOpenHelper);
};

class CreateTemporaryHelper : public FileHelper {
 public:
  CreateTemporaryHelper(FileProxy* proxy, File file)
      : FileHelper(proxy, file.Pass()) {
  }

  void RunWork(uint32 additional_file_flags) {
    // TODO(darin): file_util should have a variant of CreateTemporaryFile
    // that returns a FilePath and a File.
    if (!CreateTemporaryFile(&file_path_)) {
      // TODO(davidben): base::CreateTemporaryFile should preserve the error
      // code.
      error_ = File::FILE_ERROR_FAILED;
      return;
    }

    uint32 file_flags = File::FLAG_WRITE |
                        File::FLAG_TEMPORARY |
                        File::FLAG_CREATE_ALWAYS |
                        additional_file_flags;

    file_.Initialize(file_path_, file_flags);
    if (file_.IsValid()) {
      error_ = File::FILE_OK;
    } else {
      error_ = file_.error_details();
      DeleteFile(file_path_, false);
      file_path_.clear();
    }
  }

  void Reply(const FileProxy::CreateTemporaryCallback& callback) {
    DCHECK(!callback.is_null());
    PassFile();
    callback.Run(error_, file_path_);
  }

 private:
  FilePath file_path_;
  DISALLOW_COPY_AND_ASSIGN(CreateTemporaryHelper);
};

class GetInfoHelper : public FileHelper {
 public:
  GetInfoHelper(FileProxy* proxy, File file)
      : FileHelper(proxy, file.Pass()) {
  }

  void RunWork() {
    if (file_.GetInfo(&file_info_))
      error_  = File::FILE_OK;
  }

  void Reply(const FileProxy::GetFileInfoCallback& callback) {
    PassFile();
    DCHECK(!callback.is_null());
    callback.Run(error_, file_info_);
  }

 private:
  File::Info file_info_;
  DISALLOW_COPY_AND_ASSIGN(GetInfoHelper);
};

class ReadHelper : public FileHelper {
 public:
  ReadHelper(FileProxy* proxy, File file, int bytes_to_read)
      : FileHelper(proxy, file.Pass()),
        buffer_(new char[bytes_to_read]),
        bytes_to_read_(bytes_to_read),
        bytes_read_(0) {
  }

  void RunWork(int64 offset) {
    bytes_read_ = file_.Read(offset, buffer_.get(), bytes_to_read_);
    error_ = (bytes_read_ < 0) ? File::FILE_ERROR_FAILED : File::FILE_OK;
  }

  void Reply(const FileProxy::ReadCallback& callback) {
    PassFile();
    DCHECK(!callback.is_null());
    callback.Run(error_, buffer_.get(), bytes_read_);
  }

 private:
  scoped_ptr<char[]> buffer_;
  int bytes_to_read_;
  int bytes_read_;
  DISALLOW_COPY_AND_ASSIGN(ReadHelper);
};

class WriteHelper : public FileHelper {
 public:
  WriteHelper(FileProxy* proxy,
              File file,
              const char* buffer, int bytes_to_write)
      : FileHelper(proxy, file.Pass()),
        buffer_(new char[bytes_to_write]),
        bytes_to_write_(bytes_to_write),
        bytes_written_(0) {
    memcpy(buffer_.get(), buffer, bytes_to_write);
  }

  void RunWork(int64 offset) {
    bytes_written_ = file_.Write(offset, buffer_.get(), bytes_to_write_);
    error_ = (bytes_written_ < 0) ? File::FILE_ERROR_FAILED : File::FILE_OK;
  }

  void Reply(const FileProxy::WriteCallback& callback) {
    PassFile();
    if (!callback.is_null())
      callback.Run(error_, bytes_written_);
  }

 private:
  scoped_ptr<char[]> buffer_;
  int bytes_to_write_;
  int bytes_written_;
  DISALLOW_COPY_AND_ASSIGN(WriteHelper);
};

}  // namespace

FileProxy::FileProxy(TaskRunner* task_runner) : task_runner_(task_runner) {
}

FileProxy::~FileProxy() {
  if (file_.IsValid())
    task_runner_->PostTask(FROM_HERE, Bind(&FileDeleter, Passed(&file_)));
}

bool FileProxy::CreateOrOpen(const FilePath& file_path,
                             uint32 file_flags,
                             const StatusCallback& callback) {
  DCHECK(!file_.IsValid());
  CreateOrOpenHelper* helper = new CreateOrOpenHelper(this, File());
  return task_runner_->PostTaskAndReply(
      FROM_HERE,
      Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), file_path,
           file_flags),
      Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback));
}

bool FileProxy::CreateTemporary(uint32 additional_file_flags,
                                const CreateTemporaryCallback& callback) {
  DCHECK(!file_.IsValid());
  CreateTemporaryHelper* helper = new CreateTemporaryHelper(this, File());
  return task_runner_->PostTaskAndReply(
      FROM_HERE,
      Bind(&CreateTemporaryHelper::RunWork, Unretained(helper),
           additional_file_flags),
      Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback));
}

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

void FileProxy::SetFile(File file) {
  DCHECK(!file_.IsValid());
  file_ = file.Pass();
}

File FileProxy::TakeFile() {
  return file_.Pass();
}

PlatformFile FileProxy::GetPlatformFile() const {
  return file_.GetPlatformFile();
}

bool FileProxy::Close(const StatusCallback& callback) {
  DCHECK(file_.IsValid());
  GenericFileHelper* helper = new GenericFileHelper(this, file_.Pass());
  return task_runner_->PostTaskAndReply(
      FROM_HERE,
      Bind(&GenericFileHelper::Close, Unretained(helper)),
      Bind(&GenericFileHelper::Reply, Owned(helper), callback));
}

bool FileProxy::GetInfo(const GetFileInfoCallback& callback) {
  DCHECK(file_.IsValid());
  GetInfoHelper* helper = new GetInfoHelper(this, file_.Pass());
  return task_runner_->PostTaskAndReply(
      FROM_HERE,
      Bind(&GetInfoHelper::RunWork, Unretained(helper)),
      Bind(&GetInfoHelper::Reply, Owned(helper), callback));
}

bool FileProxy::Read(int64 offset,
                     int bytes_to_read,
                     const ReadCallback& callback) {
  DCHECK(file_.IsValid());
  if (bytes_to_read < 0)
    return false;

  ReadHelper* helper = new ReadHelper(this, file_.Pass(), bytes_to_read);
  return task_runner_->PostTaskAndReply(
      FROM_HERE,
      Bind(&ReadHelper::RunWork, Unretained(helper), offset),
      Bind(&ReadHelper::Reply, Owned(helper), callback));
}

bool FileProxy::Write(int64 offset,
                      const char* buffer,
                      int bytes_to_write,
                      const WriteCallback& callback) {
  DCHECK(file_.IsValid());
  if (bytes_to_write <= 0 || buffer == NULL)
    return false;

  WriteHelper* helper =
      new WriteHelper(this, file_.Pass(), buffer, bytes_to_write);
  return task_runner_->PostTaskAndReply(
      FROM_HERE,
      Bind(&WriteHelper::RunWork, Unretained(helper), offset),
      Bind(&WriteHelper::Reply, Owned(helper), callback));
}

bool FileProxy::SetTimes(Time last_access_time,
                         Time last_modified_time,
                         const StatusCallback& callback) {
  DCHECK(file_.IsValid());
  GenericFileHelper* helper = new GenericFileHelper(this, file_.Pass());
  return task_runner_->PostTaskAndReply(
      FROM_HERE,
      Bind(&GenericFileHelper::SetTimes, Unretained(helper), last_access_time,
           last_modified_time),
      Bind(&GenericFileHelper::Reply, Owned(helper), callback));
}

bool FileProxy::SetLength(int64 length, const StatusCallback& callback) {
  DCHECK(file_.IsValid());
  GenericFileHelper* helper = new GenericFileHelper(this, file_.Pass());
  return task_runner_->PostTaskAndReply(
      FROM_HERE,
      Bind(&GenericFileHelper::SetLength, Unretained(helper), length),
      Bind(&GenericFileHelper::Reply, Owned(helper), callback));
}

bool FileProxy::Flush(const StatusCallback& callback) {
  DCHECK(file_.IsValid());
  GenericFileHelper* helper = new GenericFileHelper(this, file_.Pass());
  return task_runner_->PostTaskAndReply(
      FROM_HERE,
      Bind(&GenericFileHelper::Flush, Unretained(helper)),
      Bind(&GenericFileHelper::Reply, Owned(helper), callback));
}

}  // namespace base
