// Copyright 2017 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 "remoting/host/file_proxy_wrapper.h"

#include <cstring>
#include <memory>
#include <queue>
#include <string>
#include <vector>

#include "base/files/file_util.h"
#include "base/memory/ptr_util.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/task_runner_util.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_checker.h"
#include "remoting/base/compound_buffer.h"

namespace {

void EmptyStatusCallback(base::File::Error error) {}

constexpr char kTempFileExtension[] = ".crdownload";

remoting::protocol::FileTransferResponse_ErrorCode FileErrorToResponseError(
    base::File::Error file_error) {
  switch (file_error) {
    case base::File::FILE_ERROR_ACCESS_DENIED:
      return remoting::protocol::
          FileTransferResponse_ErrorCode_PERMISSIONS_ERROR;
    case base::File::FILE_ERROR_NO_SPACE:
      return remoting::protocol::
          FileTransferResponse_ErrorCode_OUT_OF_DISK_SPACE;
    default:
      return remoting::protocol::FileTransferResponse_ErrorCode_FILE_IO_ERROR;
  }
}

}  // namespace

namespace remoting {

class FileProxyWrapperLinux : public FileProxyWrapper {
 public:
  FileProxyWrapperLinux();
  ~FileProxyWrapperLinux() override;

  // FileProxyWrapper implementation.
  void Init(StatusCallback status_callback) override;
  void CreateFile(const base::FilePath& directory,
                  const std::string& filename) override;
  void OpenFile(const base::FilePath& filepath,
                OpenFileCallback open_callback) override;
  void WriteChunk(std::unique_ptr<CompoundBuffer> buffer) override;
  void ReadChunk(uint64_t chunk_size, ReadCallback read_callback) override;
  void Close() override;
  void Cancel() override;
  State state() override;

 private:
  enum Mode {
    // Neither CreateFile() nor OpenFile() has been called yet.
    kUnknown = 0,

    // CreateFile() has been called.
    kWriting = 1,

    // OpenFile() has been called.
    kReading = 2,
  } mode_ = kUnknown;

  struct FileChunk {
    int64_t write_offset;
    std::vector<char> data;
  };

  // Callbacks for CreateFile().
  void CreateTempFile(int unique_path_number);
  void CreateTempFileCallback(base::File::Error error);

  // Callbacks for OpenFile().
  void OpenCallback(base::File::Error error);
  void GetInfoCallback(base::File::Error error, const base::File::Info& info);

  // Callbacks for WriteChunk().
  void WriteFileChunk(std::unique_ptr<FileChunk> chunk);
  void WriteCallback(base::File::Error error, int bytes_written);

  // Callbacks for ReadChunk().
  void ReadChunkCallback(base::File::Error error,
                         const char* data,
                         int bytes_read);

  // Callbacks for Close().
  void CloseFileAndMoveToDestination();
  void CloseCallback(base::File::Error error);
  void MoveToDestination(int unique_path_number);
  void MoveFileCallback(bool success);

  void CancelWithError(protocol::FileTransferResponse_ErrorCode error);
  void SetState(State state);

  State state_ = kUninitialized;
  scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
  std::unique_ptr<base::FileProxy> file_proxy_;

  StatusCallback status_callback_;

  // CreateFile() state - for writing only
  bool temp_file_created_ = false;
  base::FilePath temp_filepath_;
  base::FilePath destination_filepath_;

  // OpenFile() state - for reading only
  base::FilePath read_filepath_;
  OpenFileCallback open_callback_;

  // WriteChunk() state - for writing only
  int64_t next_write_file_offset_ = 0;
  std::queue<std::unique_ptr<FileChunk>> file_chunks_;
  // active_file_chunk_ is the chunk currently being written to disk. It is
  // empty if nothing is being written to disk right now.
  std::unique_ptr<FileChunk> active_file_chunk_;

  // ReadChunk() state - for reading only
  ReadCallback read_callback_;
  uint64_t expected_bytes_read_ = 0;
  int64_t next_read_file_offset_ = 0;

  base::ThreadChecker thread_checker_;
  base::WeakPtr<FileProxyWrapperLinux> weak_ptr_;
  base::WeakPtrFactory<FileProxyWrapperLinux> weak_factory_;
};

FileProxyWrapperLinux::FileProxyWrapperLinux() : weak_factory_(this) {
  weak_ptr_ = weak_factory_.GetWeakPtr();
}

FileProxyWrapperLinux::~FileProxyWrapperLinux() {
  DCHECK(thread_checker_.CalledOnValidThread());
}

void FileProxyWrapperLinux::Init(StatusCallback status_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  SetState(kInitialized);
  status_callback_ = std::move(status_callback);

  file_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
      {base::MayBlock(), base::TaskPriority::BACKGROUND});
  DCHECK(file_task_runner_);

  file_proxy_.reset(new base::FileProxy(file_task_runner_.get()));

  if (!file_task_runner_) {
    CancelWithError(protocol::FileTransferResponse_ErrorCode_UNEXPECTED_ERROR);
  }
}

void FileProxyWrapperLinux::CreateFile(const base::FilePath& directory,
                                       const std::string& filename) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_EQ(mode_, kUnknown);
  mode_ = kWriting;
  SetState(kReady);

  destination_filepath_ = directory.Append(filename);
  temp_filepath_ = destination_filepath_.AddExtension(kTempFileExtension);

  PostTaskAndReplyWithResult(
      file_task_runner_.get(), FROM_HERE,
      base::BindOnce(&base::GetUniquePathNumber, temp_filepath_,
                     base::FilePath::StringType()),
      base::BindOnce(&FileProxyWrapperLinux::CreateTempFile, weak_ptr_));
}

void FileProxyWrapperLinux::CreateTempFile(int unique_path_number) {
  if (unique_path_number > 0) {
    temp_filepath_ = temp_filepath_.InsertBeforeExtensionASCII(
        base::StringPrintf(" (%d)", unique_path_number));
  }
  if (!file_proxy_->CreateOrOpen(
          temp_filepath_, base::File::FLAG_CREATE | base::File::FLAG_WRITE,
          base::Bind(&FileProxyWrapperLinux::CreateTempFileCallback,
                     weak_ptr_))) {
    // file_proxy_ failed to post a task to file_task_runner_.
    CancelWithError(protocol::FileTransferResponse_ErrorCode_UNEXPECTED_ERROR);
  }
}

void FileProxyWrapperLinux::CreateTempFileCallback(base::File::Error error) {
  if (error) {
    LOG(ERROR) << "Creating temp file \"" << temp_filepath_.value()
               << "\" failed with error: " << error;
    CancelWithError(FileErrorToResponseError(error));
  } else {
    // Now that the temp file has been created successfully, we could lock it
    // using base::File::Lock(), but this would not prevent the file from being
    // deleted. When the file is deleted, WriteChunk() will continue to write to
    // the file as if the file was still there, and an error will occur when
    // calling base::Move() to move the temp file. Chrome exhibits the same
    // behavior with its downloads.
    temp_file_created_ = true;
    // Chunks to write may have been queued while we were creating the file,
    // start writing them now if there were any.
    if (!file_chunks_.empty()) {
      std::unique_ptr<FileChunk> chunk_to_write =
          std::move(file_chunks_.front());
      file_chunks_.pop();
      WriteFileChunk(std::move(chunk_to_write));
    }
  }
}

void FileProxyWrapperLinux::OpenFile(const base::FilePath& filepath,
                                     OpenFileCallback open_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_EQ(mode_, kUnknown);
  mode_ = kReading;

  read_filepath_ = filepath;
  open_callback_ = std::move(open_callback);

  if (!file_proxy_->CreateOrOpen(
          read_filepath_, base::File::FLAG_OPEN | base::File::FLAG_READ,
          base::Bind(&FileProxyWrapperLinux::OpenCallback, weak_ptr_))) {
    // file_proxy_ failed to post a task to file_task_runner_.
    CancelWithError(protocol::FileTransferResponse_ErrorCode_UNEXPECTED_ERROR);
  }
}

void FileProxyWrapperLinux::OpenCallback(base::File::Error error) {
  if (error) {
    LOG(ERROR) << "Opening file \"" << read_filepath_.value()
               << "\" failed with error: " << error;
    CancelWithError(FileErrorToResponseError(error));
    return;
  }

  if (!file_proxy_->GetInfo(
          base::Bind(&FileProxyWrapperLinux::GetInfoCallback, weak_ptr_))) {
    // file_proxy_ failed to post a task to file_task_runner_.
    CancelWithError(protocol::FileTransferResponse_ErrorCode_UNEXPECTED_ERROR);
  }
}

void FileProxyWrapperLinux::GetInfoCallback(base::File::Error error,
                                            const base::File::Info& info) {
  if (error) {
    LOG(ERROR) << "Getting file info failed with error: " << error;
    CancelWithError(FileErrorToResponseError(error));
    return;
  }

  if (info.is_directory) {
    LOG(ERROR) << "Tried to open directory for reading chunks.";
    CancelWithError(protocol::FileTransferResponse_ErrorCode_UNEXPECTED_ERROR);
    return;
  }

  SetState(kReady);
  std::move(open_callback_).Run(info.size);
}

void FileProxyWrapperLinux::WriteChunk(std::unique_ptr<CompoundBuffer> buffer) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_EQ(mode_, kWriting);
  DCHECK_EQ(state_, kReady);

  std::unique_ptr<FileChunk> new_file_chunk = base::WrapUnique(new FileChunk());
  new_file_chunk->data.resize(buffer->total_bytes());
  // This copy could be avoided if CompoundBuffer were updated to allowed us to
  // access the individual buffers in |buffer|.
  // TODO(jarhar): Update CompoundBuffer to allow data transfer without a
  // memcopy.
  buffer->CopyTo(new_file_chunk->data.data(), new_file_chunk->data.size());

  new_file_chunk->write_offset = next_write_file_offset_;
  next_write_file_offset_ += new_file_chunk->data.size();

  // If the file hasn't been created yet or there is another chunk currently
  // being written, we have to queue this chunk to be written later.
  if (!temp_file_created_ || active_file_chunk_) {
    // TODO(jarhar): When flow control enabled QUIC-based WebRTC data channels
    // are implemented, block the flow of incoming chunks here if
    // file_chunks_ has reached a maximum size. This implementation will
    // allow file_chunks_ to grow without limits.
    file_chunks_.push(std::move(new_file_chunk));
  } else {
    WriteFileChunk(std::move(new_file_chunk));
  }
}

void FileProxyWrapperLinux::WriteFileChunk(std::unique_ptr<FileChunk> chunk) {
  active_file_chunk_ = std::move(chunk);
  DCHECK(active_file_chunk_);
  if (!file_proxy_->Write(
          active_file_chunk_->write_offset, active_file_chunk_->data.data(),
          active_file_chunk_->data.size(),
          base::Bind(&FileProxyWrapperLinux::WriteCallback, weak_ptr_))) {
    // file_proxy_ failed to post a task to file_task_runner_.
    CancelWithError(protocol::FileTransferResponse_ErrorCode_UNEXPECTED_ERROR);
  }
}

void FileProxyWrapperLinux::WriteCallback(base::File::Error error,
                                          int bytes_written) {
  if (active_file_chunk_->data.size() != static_cast<unsigned>(bytes_written) ||
      error) {
    if (!error) {
      error = base::File::FILE_ERROR_FAILED;
    }
    LOG(ERROR) << "Write failed with error: " << error;
    CancelWithError(FileErrorToResponseError(error));
    return;
  }

  active_file_chunk_.reset();
  if (!file_chunks_.empty()) {
    std::unique_ptr<FileChunk> chunk_to_write = std::move(file_chunks_.front());
    file_chunks_.pop();
    WriteFileChunk(std::move(chunk_to_write));
  } else if (state_ == kBusy) {
    // All writes are complete and we have gotten the signal to move the file.
    CloseFileAndMoveToDestination();
  }
}

void FileProxyWrapperLinux::ReadChunk(uint64_t size,
                                      ReadCallback read_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_EQ(mode_, kReading);
  SetState(kBusy);

  expected_bytes_read_ = size;
  read_callback_ = std::move(read_callback);

  if (!file_proxy_->Read(
          next_read_file_offset_, expected_bytes_read_,
          base::Bind(&FileProxyWrapperLinux::ReadChunkCallback, weak_ptr_))) {
    // file_proxy_ failed to post a task to file_task_runner_.
    CancelWithError(protocol::FileTransferResponse_ErrorCode_UNEXPECTED_ERROR);
  }
}

void FileProxyWrapperLinux::ReadChunkCallback(base::File::Error error,
                                              const char* data,
                                              int bytes_read) {
  if (static_cast<unsigned>(bytes_read) != expected_bytes_read_ || error) {
    if (!error) {
      error = base::File::FILE_ERROR_FAILED;
    }
    LOG(ERROR) << "Read failed with error: " << error;
    CancelWithError(FileErrorToResponseError(error));
    return;
  }

  next_read_file_offset_ += bytes_read;

  std::unique_ptr<std::vector<char>> read_buffer =
      base::MakeUnique<std::vector<char>>();
  read_buffer->resize(bytes_read);
  memcpy(read_buffer->data(), data, read_buffer->size());

  SetState(kReady);
  std::move(read_callback_).Run(std::move(read_buffer));
}

void FileProxyWrapperLinux::Close() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_EQ(state_, kReady);

  if (mode_ == kWriting) {
    SetState(kBusy);
    if (!active_file_chunk_ && file_chunks_.empty()) {
      // All writes are complete, so we can finish up now.
      CloseFileAndMoveToDestination();
    }
    return;
  }

  file_proxy_->Close(base::Bind(&EmptyStatusCallback));
  SetState(kClosed);
}

void FileProxyWrapperLinux::CloseFileAndMoveToDestination() {
  DCHECK_EQ(state_, kBusy);
  file_proxy_->Close(
      base::Bind(&FileProxyWrapperLinux::CloseCallback, weak_ptr_));
}

void FileProxyWrapperLinux::CloseCallback(base::File::Error error) {
  if (error) {
    CancelWithError(FileErrorToResponseError(error));
    return;
  }

  PostTaskAndReplyWithResult(
      file_task_runner_.get(), FROM_HERE,
      base::BindOnce(&base::GetUniquePathNumber, destination_filepath_,
                     base::FilePath::StringType()),
      base::BindOnce(&FileProxyWrapperLinux::MoveToDestination, weak_ptr_));
}

void FileProxyWrapperLinux::MoveToDestination(int unique_path_number) {
  if (unique_path_number > 0) {
    destination_filepath_ = destination_filepath_.InsertBeforeExtensionASCII(
        base::StringPrintf(" (%d)", unique_path_number));
  }
  PostTaskAndReplyWithResult(
      file_task_runner_.get(), FROM_HERE,
      base::BindOnce(&base::Move, temp_filepath_, destination_filepath_),
      base::BindOnce(&FileProxyWrapperLinux::MoveFileCallback, weak_ptr_));
}

void FileProxyWrapperLinux::MoveFileCallback(bool success) {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (success) {
    SetState(kClosed);
    std::move(status_callback_)
        .Run(state_,
             base::Optional<protocol::FileTransferResponse_ErrorCode>());
  } else {
    CancelWithError(protocol::FileTransferResponse_ErrorCode_FILE_IO_ERROR);
  }
}

void FileProxyWrapperLinux::Cancel() {
  if (file_proxy_->IsValid()) {
    file_proxy_->Close(base::Bind(&EmptyStatusCallback));
  }

  if (mode_ == kWriting) {
    if (state_ == kReady || state_ == kBusy) {
      file_task_runner_->PostTask(
          FROM_HERE, base::BindOnce(base::IgnoreResult(&base::DeleteFile),
                                    temp_filepath_, false /* recursive */));
    }

    if (state_ == kBusy || state_ == kClosed) {
      file_task_runner_->PostTask(
          FROM_HERE,
          base::BindOnce(base::IgnoreResult(&base::DeleteFile),
                         destination_filepath_, false /* recursive */));
    }
  }

  SetState(kFailed);
}

void FileProxyWrapperLinux::CancelWithError(
    protocol::FileTransferResponse_ErrorCode error) {
  Cancel();
  std::move(status_callback_)
      .Run(state_,
           base::Optional<protocol::FileTransferResponse_ErrorCode>(error));
}

void FileProxyWrapperLinux::SetState(State state) {
  switch (state) {
    case kUninitialized:
      // No state can change to kUninitialized.
      NOTREACHED();
      break;
    case kInitialized:
      DCHECK_EQ(state_, kUninitialized);
      break;
    case kReady:
      DCHECK(state_ == kInitialized || state_ == kBusy);
      break;
    case kBusy:
      DCHECK_EQ(state_, kReady);
      break;
    case kClosed:
      DCHECK(state_ == kReady || state_ == kBusy);
      break;
    case kFailed:
      // Any state can change to kFailed.
      break;
  }

  state_ = state;
}

FileProxyWrapper::State FileProxyWrapperLinux::state() {
  return state_;
}

// static
std::unique_ptr<FileProxyWrapper> FileProxyWrapper::Create() {
  return base::WrapUnique(new FileProxyWrapperLinux());
}

}  // namespace remoting
