// Copyright (c) 2013 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 "ppapi/proxy/url_loader_resource.h"

#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_url_loader.h"
#include "ppapi/proxy/dispatch_reply_message.h"
#include "ppapi/proxy/file_ref_resource.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/url_request_info_resource.h"
#include "ppapi/proxy/url_response_info_resource.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/url_response_info_data.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/resource_creation_api.h"

using ppapi::thunk::EnterResourceNoLock;
using ppapi::thunk::PPB_URLLoader_API;
using ppapi::thunk::PPB_URLRequestInfo_API;

#ifdef _MSC_VER
// Do not warn about use of std::copy with raw pointers.
#pragma warning(disable : 4996)
#endif

namespace ppapi {
namespace proxy {

URLLoaderResource::URLLoaderResource(Connection connection,
                                     PP_Instance instance)
    : PluginResource(connection, instance),
      mode_(MODE_WAITING_TO_OPEN),
      status_callback_(NULL),
      bytes_sent_(0),
      total_bytes_to_be_sent_(-1),
      bytes_received_(0),
      total_bytes_to_be_received_(-1),
      user_buffer_(NULL),
      user_buffer_size_(0),
      done_status_(PP_OK_COMPLETIONPENDING),
      is_streaming_to_file_(false),
      is_asynchronous_load_suspended_(false) {
  SendCreate(RENDERER, PpapiHostMsg_URLLoader_Create());
}

URLLoaderResource::URLLoaderResource(Connection connection,
                                     PP_Instance instance,
                                     int pending_main_document_loader_id,
                                     const ppapi::URLResponseInfoData& data)
    : PluginResource(connection, instance),
      mode_(MODE_OPENING),
      status_callback_(NULL),
      bytes_sent_(0),
      total_bytes_to_be_sent_(-1),
      bytes_received_(0),
      total_bytes_to_be_received_(-1),
      user_buffer_(NULL),
      user_buffer_size_(0),
      done_status_(PP_OK_COMPLETIONPENDING),
      is_streaming_to_file_(false),
      is_asynchronous_load_suspended_(false) {
  AttachToPendingHost(RENDERER, pending_main_document_loader_id);
  SaveResponseInfo(data);
}

URLLoaderResource::~URLLoaderResource() {
}

PPB_URLLoader_API* URLLoaderResource::AsPPB_URLLoader_API() {
  return this;
}

int32_t URLLoaderResource::Open(PP_Resource request_id,
                                scoped_refptr<TrackedCallback> callback) {
  EnterResourceNoLock<PPB_URLRequestInfo_API> enter_request(request_id, true);
  if (enter_request.failed()) {
    Log(PP_LOGLEVEL_ERROR,
        "PPB_URLLoader.Open: invalid request resource ID. (Hint to C++ wrapper"
        " users: use the ResourceRequest constructor that takes an instance or"
        " else the request will be null.)");
    return PP_ERROR_BADARGUMENT;
  }
  return Open(enter_request.object()->GetData(), 0, callback);
}

int32_t URLLoaderResource::Open(
    const ::ppapi::URLRequestInfoData& request_data,
    int requestor_pid,
    scoped_refptr<TrackedCallback> callback) {
  int32_t rv = ValidateCallback(callback);
  if (rv != PP_OK)
    return rv;
  if (mode_ != MODE_WAITING_TO_OPEN)
    return PP_ERROR_INPROGRESS;

  request_data_ = request_data;

  mode_ = MODE_OPENING;
  is_asynchronous_load_suspended_ = false;

  RegisterCallback(callback);
  Post(RENDERER, PpapiHostMsg_URLLoader_Open(request_data));
  return PP_OK_COMPLETIONPENDING;
}

int32_t URLLoaderResource::FollowRedirect(
    scoped_refptr<TrackedCallback> callback) {
  int32_t rv = ValidateCallback(callback);
  if (rv != PP_OK)
    return rv;
  if (mode_ != MODE_OPENING)
    return PP_ERROR_INPROGRESS;

  SetDefersLoading(false);  // Allow the redirect to continue.
  RegisterCallback(callback);
  return PP_OK_COMPLETIONPENDING;
}

PP_Bool URLLoaderResource::GetUploadProgress(int64_t* bytes_sent,
                                              int64_t* total_bytes_to_be_sent) {
  if (!request_data_.record_upload_progress) {
    *bytes_sent = 0;
    *total_bytes_to_be_sent = 0;
    return PP_FALSE;
  }
  *bytes_sent = bytes_sent_;
  *total_bytes_to_be_sent = total_bytes_to_be_sent_;
  return PP_TRUE;
}

PP_Bool URLLoaderResource::GetDownloadProgress(
    int64_t* bytes_received,
    int64_t* total_bytes_to_be_received) {
  if (!request_data_.record_download_progress) {
    *bytes_received = 0;
    *total_bytes_to_be_received = 0;
    return PP_FALSE;
  }
  *bytes_received = bytes_received_;
  *total_bytes_to_be_received = total_bytes_to_be_received_;
  return PP_TRUE;
}

PP_Resource URLLoaderResource::GetResponseInfo() {
  if (response_info_.get())
    return response_info_->GetReference();
  return 0;
}

int32_t URLLoaderResource::ReadResponseBody(
    void* buffer,
    int32_t bytes_to_read,
    scoped_refptr<TrackedCallback> callback) {
  int32_t rv = ValidateCallback(callback);
  if (rv != PP_OK)
    return rv;
  if (!response_info_.get())
    return PP_ERROR_FAILED;

  // Fail if we have a valid file ref.
  // ReadResponseBody() is for reading to a user-provided buffer.
  if (response_info_->data().body_as_file_ref.IsValid())
    return PP_ERROR_FAILED;

  if (bytes_to_read <= 0 || !buffer)
    return PP_ERROR_BADARGUMENT;

  user_buffer_ = static_cast<char*>(buffer);
  user_buffer_size_ = bytes_to_read;

  if (!buffer_.empty())
    return FillUserBuffer();

  // We may have already reached EOF.
  if (done_status_ != PP_OK_COMPLETIONPENDING) {
    user_buffer_ = NULL;
    user_buffer_size_ = 0;
    return done_status_;
  }

  RegisterCallback(callback);
  return PP_OK_COMPLETIONPENDING;
}

int32_t URLLoaderResource::FinishStreamingToFile(
    scoped_refptr<TrackedCallback> callback) {
  int32_t rv = ValidateCallback(callback);
  if (rv != PP_OK)
    return rv;
  if (!response_info_.get())
    return PP_ERROR_FAILED;

  // Fail if we do not have a valid file ref.
  if (!response_info_->data().body_as_file_ref.IsValid())
    return PP_ERROR_FAILED;

  // We may have already reached EOF.
  if (done_status_ != PP_OK_COMPLETIONPENDING)
    return done_status_;

  is_streaming_to_file_ = true;
  if (is_asynchronous_load_suspended_)
    SetDefersLoading(false);

  // Wait for didFinishLoading / didFail.
  RegisterCallback(callback);
  return PP_OK_COMPLETIONPENDING;
}

void URLLoaderResource::Close() {
  mode_ = MODE_LOAD_COMPLETE;
  done_status_ = PP_ERROR_ABORTED;

  Post(RENDERER, PpapiHostMsg_URLLoader_Close());

  // Abort the callbacks, the plugin doesn't want to be called back after this.
  // TODO(brettw) this should fix bug 69457, mark it fixed. ============
  if (TrackedCallback::IsPending(pending_callback_))
    pending_callback_->PostAbort();
}

void URLLoaderResource::GrantUniversalAccess() {
  Post(RENDERER, PpapiHostMsg_URLLoader_GrantUniversalAccess());
}

void URLLoaderResource::RegisterStatusCallback(
    PP_URLLoaderTrusted_StatusCallback callback) {
  status_callback_ = callback;
}

void URLLoaderResource::OnReplyReceived(
    const ResourceMessageReplyParams& params,
    const IPC::Message& msg) {
  PPAPI_BEGIN_MESSAGE_MAP(URLLoaderResource, msg)
    case PpapiPluginMsg_URLLoader_SendData::ID:
      // Special message, manually dispatch since we don't want the automatic
      // unpickling.
      OnPluginMsgSendData(params, msg);
      break;

    PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
        PpapiPluginMsg_URLLoader_ReceivedResponse,
        OnPluginMsgReceivedResponse)
    PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
        PpapiPluginMsg_URLLoader_FinishedLoading,
        OnPluginMsgFinishedLoading)
    PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
        PpapiPluginMsg_URLLoader_UpdateProgress,
        OnPluginMsgUpdateProgress)
  PPAPI_END_MESSAGE_MAP()
}

void URLLoaderResource::OnPluginMsgReceivedResponse(
    const ResourceMessageReplyParams& params,
    const URLResponseInfoData& data) {
  SaveResponseInfo(data);
  RunCallback(PP_OK);
}

void URLLoaderResource::OnPluginMsgSendData(
    const ResourceMessageReplyParams& params,
    const IPC::Message& message) {
  base::PickleIterator iter(message);
  const char* data;
  int data_length;
  if (!iter.ReadData(&data, &data_length)) {
    NOTREACHED() << "Expecting data";
    return;
  }

  mode_ = MODE_STREAMING_DATA;
  buffer_.insert(buffer_.end(), data, data + data_length);

  // To avoid letting the network stack download an entire stream all at once,
  // defer loading when we have enough buffer.
  // Check for this before we run the callback, even though that could move
  // data out of the buffer. Doing anything after the callback is unsafe.
  DCHECK(request_data_.prefetch_buffer_lower_threshold <
         request_data_.prefetch_buffer_upper_threshold);
  if (!is_streaming_to_file_ &&
      !is_asynchronous_load_suspended_ &&
      (buffer_.size() >= static_cast<size_t>(
          request_data_.prefetch_buffer_upper_threshold))) {
    DVLOG(1) << "Suspending async load - buffer size: " << buffer_.size();
    SetDefersLoading(true);
  }

  if (user_buffer_)
    RunCallback(FillUserBuffer());
  else
    DCHECK(!TrackedCallback::IsPending(pending_callback_));
}

void URLLoaderResource::OnPluginMsgFinishedLoading(
    const ResourceMessageReplyParams& params,
    int32_t result) {
  mode_ = MODE_LOAD_COMPLETE;
  done_status_ = result;
  user_buffer_ = NULL;
  user_buffer_size_ = 0;

  // If the client hasn't called any function that takes a callback since
  // the initial call to Open, or called ReadResponseBody and got a
  // synchronous return, then the callback will be NULL.
  if (TrackedCallback::IsPending(pending_callback_))
    RunCallback(done_status_);
}

void URLLoaderResource::OnPluginMsgUpdateProgress(
    const ResourceMessageReplyParams& params,
    int64_t bytes_sent,
    int64_t total_bytes_to_be_sent,
    int64_t bytes_received,
    int64_t total_bytes_to_be_received) {
  bytes_sent_ = bytes_sent;
  total_bytes_to_be_sent_ = total_bytes_to_be_sent;
  bytes_received_ = bytes_received;
  total_bytes_to_be_received_ = total_bytes_to_be_received;

  if (status_callback_)
    status_callback_(pp_instance(), pp_resource(),
                     bytes_sent_, total_bytes_to_be_sent_,
                     bytes_received_, total_bytes_to_be_received_);
}

void URLLoaderResource::SetDefersLoading(bool defers_loading) {
  Post(RENDERER, PpapiHostMsg_URLLoader_SetDeferLoading(defers_loading));
}

int32_t URLLoaderResource::ValidateCallback(
    scoped_refptr<TrackedCallback> callback) {
  DCHECK(callback.get());
  if (TrackedCallback::IsPending(pending_callback_))
    return PP_ERROR_INPROGRESS;
  return PP_OK;
}

void URLLoaderResource::RegisterCallback(
    scoped_refptr<TrackedCallback> callback) {
  DCHECK(!TrackedCallback::IsPending(pending_callback_));
  pending_callback_ = callback;
}

void URLLoaderResource::RunCallback(int32_t result) {
  // This may be null when this is a main document loader.
  if (!pending_callback_.get())
    return;

  // If |user_buffer_| was set as part of registering a callback, the paths
  // which trigger that callack must have cleared it since the callback is now
  // free to delete it.
  DCHECK(!user_buffer_);

  // As a second line of defense, clear the |user_buffer_| in case the
  // callbacks get called in an unexpected order.
  user_buffer_ = NULL;
  user_buffer_size_ = 0;
  pending_callback_->Run(result);
}

void URLLoaderResource::SaveResponseInfo(const URLResponseInfoData& data) {
  // Create a proxy resource for the the file ref host resource if needed.
  PP_Resource body_as_file_ref = 0;
  if (data.body_as_file_ref.IsValid()) {
    body_as_file_ref = FileRefResource::CreateFileRef(connection(),
                                                      pp_instance(),
                                                      data.body_as_file_ref);
  }
  response_info_ = new URLResponseInfoResource(
      connection(), pp_instance(), data, body_as_file_ref);
}

int32_t URLLoaderResource::FillUserBuffer() {
  DCHECK(user_buffer_);
  DCHECK(user_buffer_size_);

  size_t bytes_to_copy = std::min(buffer_.size(), user_buffer_size_);
  std::copy(buffer_.begin(), buffer_.begin() + bytes_to_copy, user_buffer_);
  buffer_.erase(buffer_.begin(), buffer_.begin() + bytes_to_copy);

  // If the buffer is getting too empty, resume asynchronous loading.
  if (is_asynchronous_load_suspended_ &&
      buffer_.size() <= static_cast<size_t>(
          request_data_.prefetch_buffer_lower_threshold)) {
    DVLOG(1) << "Resuming async load - buffer size: " << buffer_.size();
    SetDefersLoading(false);
  }

  // Reset for next time.
  user_buffer_ = NULL;
  user_buffer_size_ = 0;
  return base::checked_cast<int32_t>(bytes_to_copy);
}

}  // namespace proxy
}  // namespace ppapi
