// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "chrome/nacl/url_loader_util.h"

#include <memory>

#include <ppapi/c/pp_file_info.h>
#include <ppapi/c/ppb_file_io.h>
#include <ppapi/cpp/file_io.h>
#include <ppapi/cpp/file_ref.h>
#include <ppapi/cpp/file_system.h>
#include <ppapi/cpp/instance.h>
#include <ppapi/cpp/url_loader.h>
#include <ppapi/cpp/url_request_info.h>
#include <ppapi/cpp/url_response_info.h>
#include <ppapi/utility/completion_callback_factory.h>

#include "base/logging.h"
#include "base/port.h"
#include "base/scoped_ptr.h"

using std::unique_ptr;

namespace mozc {
namespace chrome {
namespace nacl {

namespace {
const int32_t kReadBufferSize = 32768;

class URLLoaderStreamToFileHandler {
 public:
  URLLoaderStreamToFileHandler(pp::Instance *instance,
                               const string &url,
                               const string &file_name,
                               pp::CompletionCallback callback);
  void Start();

 private:
  // "delete this" is called in URLLoaderStreamToFileHandler::Complete().
  ~URLLoaderStreamToFileHandler();
  void StartImpl(int32_t result);
  void OnOpen(int32 result);
  void OnStreamComplete(int32 result);
  void OnInputFileOpen(int32_t result);
  void OnInputFileQuery(int32_t result);
  void OnFileSystemOpen(int32_t result);
  void OnDeleteOutputFile(int32_t result);
  void OnOutputFileOpen(int32_t result);
  void OnInputFileRead(int32_t bytes_read);
  void OnOutputFileWrite(int32_t bytes_written);
  void OnOutputFileFlush(int32_t result);
  void Complete(bool result);

  pp::Instance *instance_;
  const string url_;
  const string file_name_;
  pp::CompletionCallback callback_;
  unique_ptr<pp::URLRequestInfo> url_request_;
  unique_ptr<pp::URLLoader> url_loader_;
  pp::URLResponseInfo url_response_;
  pp::FileRef body_file_ref_;
  pp::CompletionCallbackFactory<URLLoaderStreamToFileHandler> callback_factory_;
  unique_ptr<pp::FileSystem> file_system_;
  unique_ptr<pp::FileRef> output_file_ref_;
  unique_ptr<pp::FileIO> output_file_io_;
  unique_ptr<pp::FileIO> input_file_io_;
  PP_FileInfo input_file_info_;
  int64_t total_read_bytes_;
  int64_t total_written_bytes_;
  int64_t buffer_written_bytes_;
  unique_ptr<char[]> tmp_buffer_;

  DISALLOW_COPY_AND_ASSIGN(URLLoaderStreamToFileHandler);
};

URLLoaderStreamToFileHandler::URLLoaderStreamToFileHandler(
    pp::Instance *instance,
    const string &url,
    const string &file_name,
    pp::CompletionCallback callback)
    : instance_(instance),
      url_(url),
      file_name_(file_name),
      callback_(callback),
      total_read_bytes_(0),
      total_written_bytes_(0),
      buffer_written_bytes_(0) {
}

URLLoaderStreamToFileHandler::~URLLoaderStreamToFileHandler() {
}

void URLLoaderStreamToFileHandler::Start() {
  callback_factory_.Initialize(this);
  if (pp::Module::Get()->core()->IsMainThread()) {
    StartImpl(0);
    return;
  }
  pp::Module::Get()->core()->CallOnMainThread(
      0,
      callback_factory_.NewCallback(&URLLoaderStreamToFileHandler::StartImpl));
}

void URLLoaderStreamToFileHandler::StartImpl(int32_t result) {
  CHECK(pp::Module::Get()->core()->IsMainThread());
  CHECK(!url_request_.get());
  CHECK(!url_loader_.get());
  url_request_.reset(new pp::URLRequestInfo(instance_));
  url_loader_.reset(new pp::URLLoader(instance_));
  url_request_->SetAllowCrossOriginRequests(true);
  url_request_->SetURL(url_);
  url_request_->SetMethod("GET");
  url_request_->SetStreamToFile(true);
  url_loader_->Open(*url_request_,
                    callback_factory_.NewCallback(
                        &URLLoaderStreamToFileHandler::OnOpen));
}

void URLLoaderStreamToFileHandler::OnOpen(int32 result) {
  if (result != PP_OK) {
    DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnOpen error";
    Complete(false);
    return;
  }
  const pp::URLResponseInfo response = url_loader_->GetResponseInfo();
  if (response.GetStatusCode() != 200) {
    DLOG(ERROR) << "pp::URLLoader::Open() failed: " << url_
                << " Status code: " << response.GetStatusCode();
    Complete(false);
    return;
  }
  url_loader_->FinishStreamingToFile(
      callback_factory_.NewCallback(
          &URLLoaderStreamToFileHandler::OnStreamComplete));
  url_response_ = url_loader_->GetResponseInfo();
  body_file_ref_ = url_response_.GetBodyAsFileRef();
}

void URLLoaderStreamToFileHandler::OnStreamComplete(int32 result) {
  if (result != PP_OK) {
    DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnStreamComplete error";
    Complete(false);
    return;
  }
  input_file_io_.reset(new pp::FileIO(instance_));
  const int32_t ret = input_file_io_->Open(
      body_file_ref_, PP_FILEOPENFLAG_READ,
      callback_factory_.NewCallback(
          &URLLoaderStreamToFileHandler::OnInputFileOpen));
  if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
    DLOG(ERROR) << "input_file_io_->Open error";
    Complete(false);
    return;
  }
}

void URLLoaderStreamToFileHandler::OnInputFileOpen(int32_t result) {
  if (result != PP_OK) {
    DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnInputFileOpen error";
    Complete(false);
    return;
  }
  const int32_t ret = input_file_io_->Query(
      &input_file_info_,
      callback_factory_.NewCallback(
          &URLLoaderStreamToFileHandler::OnInputFileQuery));
  if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
    DLOG(ERROR) << "input_file_io_->Query error";
    Complete(false);
    return;
  }
}
void URLLoaderStreamToFileHandler::OnInputFileQuery(int32_t result) {
  if (result != PP_OK) {
    DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnInputFileQuery error";
    Complete(false);
    return;
  }
  file_system_.reset(
      new pp::FileSystem(instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT));
  const int32_t ret = file_system_->Open(
      input_file_info_.size,
      callback_factory_.NewCallback(
          &URLLoaderStreamToFileHandler::OnFileSystemOpen));
  if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
    DLOG(ERROR) << "file_system_->Open error";
    Complete(false);
    return;
  }
}

void URLLoaderStreamToFileHandler::OnFileSystemOpen(int32_t result) {
  if (result != PP_OK) {
    DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnFileSystemOpen error";
    Complete(false);
    return;
  }
  output_file_ref_.reset(new pp::FileRef(*file_system_, file_name_.c_str()));
  const int32_t ret = output_file_ref_->Delete(
      callback_factory_.NewCallback(
          &URLLoaderStreamToFileHandler::OnDeleteOutputFile));
  if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
    DLOG(ERROR) << "output_file_ref_->Delete error";
    Complete(false);
    return;
  }
}

void URLLoaderStreamToFileHandler::OnDeleteOutputFile(int32_t result) {
  output_file_io_.reset(new pp::FileIO(instance_));
  const int32_t ret = output_file_io_->Open(
      *output_file_ref_, PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE,
      callback_factory_.NewCallback(
          &URLLoaderStreamToFileHandler::OnOutputFileOpen));
  if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
    DLOG(ERROR) << "output_file_io_->Open error";
    Complete(false);
    return;
  }
}

void URLLoaderStreamToFileHandler::OnOutputFileOpen(int32_t result) {
  if (result != PP_OK) {
    DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnOutputFileOpen error";
    Complete(false);
    return;
  }
  tmp_buffer_.reset(new char[kReadBufferSize]);
  OnInputFileRead(0);
}

void URLLoaderStreamToFileHandler::OnInputFileRead(int32_t bytes_read) {
  if (bytes_read < 0) {
    DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnInputFileRead error";
    Complete(false);
    return;
  }
  total_read_bytes_ += bytes_read;
  if (bytes_read == 0) {
    const int32_t ret = input_file_io_->Read(
        total_read_bytes_, tmp_buffer_.get(),
        min(kReadBufferSize,
            static_cast<int32_t>(input_file_info_.size - total_read_bytes_)),
        callback_factory_.NewCallback(
            &URLLoaderStreamToFileHandler::OnInputFileRead));
    if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
      DLOG(ERROR) << "input_file_io_->Read error";
      Complete(false);
      return;
    }
  } else {
    buffer_written_bytes_ = 0;
    const int32_t ret = output_file_io_->Write(
        total_written_bytes_, tmp_buffer_.get(), bytes_read,
        callback_factory_.NewCallback(
            &URLLoaderStreamToFileHandler::OnOutputFileWrite));
    if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
      DLOG(ERROR) << "output_file_io_->Write error";
      Complete(false);
      return;
    }
  }
}

void URLLoaderStreamToFileHandler::OnOutputFileWrite(int32_t bytes_written) {
  if (bytes_written < 0) {
    DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnOutputFileWrite error";
    Complete(false);
    return;
  }
  total_written_bytes_ += bytes_written;
  buffer_written_bytes_ += bytes_written;
  if (total_read_bytes_ == total_written_bytes_) {
    if (total_read_bytes_ == input_file_info_.size) {
      // Finish writing
      const int32_t ret = output_file_io_->Flush(
          callback_factory_.NewCallback(
              &URLLoaderStreamToFileHandler::OnOutputFileFlush));
      if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
        DLOG(ERROR) << "output_file_io_->Flush error";
        Complete(false);
        return;
      }
    } else {
      // Read more
      const int32_t ret = input_file_io_->Read(
          total_read_bytes_, tmp_buffer_.get(),
          min(kReadBufferSize,
              static_cast<int32_t>(input_file_info_.size - total_read_bytes_)),
          callback_factory_.NewCallback(
              &URLLoaderStreamToFileHandler::OnInputFileRead));
      if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
        DLOG(ERROR) << "input_file_io_->Read error";
        Complete(false);
        return;
      }
    }
  } else {
    // Writes more
    const int32_t ret = output_file_io_->Write(
        total_written_bytes_,
        &tmp_buffer_[buffer_written_bytes_],
        total_read_bytes_ - total_written_bytes_,
        callback_factory_.NewCallback(
            &URLLoaderStreamToFileHandler::OnOutputFileWrite));
    if ((ret != PP_OK_COMPLETIONPENDING) && (ret != PP_OK)) {
      DLOG(ERROR) << "output_file_io_->Write error";
      Complete(false);
      return;
    }
  }
}

void URLLoaderStreamToFileHandler::OnOutputFileFlush(int32_t result) {
  if (result != PP_OK) {
    DLOG(ERROR) << "URLLoaderStreamToFileHandler::OnOutputFileFlush error";
    Complete(false);
    return;
  }
  Complete(true);
}

void URLLoaderStreamToFileHandler::Complete(bool result) {
  callback_.Run(result ? PP_OK : PP_ERROR_FAILED);
  delete this;
}

}  // namespace

void URLLoaderUtil::StartDownloadToFile(pp::Instance *instance,
                                        const string &url,
                                        const string &file_name,
                                        pp::CompletionCallback callback) {
  URLLoaderStreamToFileHandler *handler =
      new URLLoaderStreamToFileHandler(instance,
                                       url,
                                       file_name,
                                       callback);
  DCHECK(handler);
  handler->Start();
}

}  // namespace nacl
}  // namespace chrome
}  // namespace mozc
