// Copyright (c) 2012 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.

// From ppb_url_loader.idl modified Tue May  7 14:43:00 2013.

#include <string.h>

#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_url_loader.h"
#include "ppapi/shared_impl/tracked_callback.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppapi_thunk_export.h"
#include "ppapi/thunk/ppb_url_loader_api.h"

namespace ppapi {
namespace thunk {

namespace {

PP_Resource Create(PP_Instance instance) {
  VLOG(4) << "PPB_URLLoader::Create()";
  EnterResourceCreation enter(instance);
  if (enter.failed())
    return 0;
  return enter.functions()->CreateURLLoader(instance);
}

PP_Bool IsURLLoader(PP_Resource resource) {
  VLOG(4) << "PPB_URLLoader::IsURLLoader()";
  EnterResource<PPB_URLLoader_API> enter(resource, false);
  return PP_FromBool(enter.succeeded());
}

int32_t Open(PP_Resource loader,
             PP_Resource request_info,
             struct PP_CompletionCallback callback) {
  VLOG(4) << "PPB_URLLoader::Open()";
  EnterResource<PPB_URLLoader_API> enter(loader, callback, true);
  if (enter.failed())
    return enter.retval();
  return enter.SetResult(enter.object()->Open(request_info, enter.callback()));
}

int32_t FollowRedirect(PP_Resource loader,
                       struct PP_CompletionCallback callback) {
  VLOG(4) << "PPB_URLLoader::FollowRedirect()";
  EnterResource<PPB_URLLoader_API> enter(loader, callback, true);
  if (enter.failed())
    return enter.retval();
  return enter.SetResult(enter.object()->FollowRedirect(enter.callback()));
}

PP_Bool GetUploadProgress(PP_Resource loader,
                          int64_t* bytes_sent,
                          int64_t* total_bytes_to_be_sent) {
  VLOG(4) << "PPB_URLLoader::GetUploadProgress()";
  EnterResource<PPB_URLLoader_API> enter(loader, true);
  if (enter.failed()) {
    memset(bytes_sent, 0, sizeof(*bytes_sent));
    memset(total_bytes_to_be_sent, 0, sizeof(*total_bytes_to_be_sent));
    return PP_FALSE;
  }
  return enter.object()->GetUploadProgress(bytes_sent, total_bytes_to_be_sent);
}

PP_Bool GetDownloadProgress(PP_Resource loader,
                            int64_t* bytes_received,
                            int64_t* total_bytes_to_be_received) {
  VLOG(4) << "PPB_URLLoader::GetDownloadProgress()";
  EnterResource<PPB_URLLoader_API> enter(loader, true);
  if (enter.failed()) {
    memset(bytes_received, 0, sizeof(*bytes_received));
    memset(total_bytes_to_be_received, 0, sizeof(*total_bytes_to_be_received));
    return PP_FALSE;
  }
  return enter.object()->GetDownloadProgress(bytes_received,
                                             total_bytes_to_be_received);
}

PP_Resource GetResponseInfo(PP_Resource loader) {
  VLOG(4) << "PPB_URLLoader::GetResponseInfo()";
  EnterResource<PPB_URLLoader_API> enter(loader, true);
  if (enter.failed())
    return 0;
  return enter.object()->GetResponseInfo();
}

int32_t ReadResponseBody(PP_Resource loader,
                         void* buffer,
                         int32_t bytes_to_read,
                         struct PP_CompletionCallback callback) {
  VLOG(4) << "PPB_URLLoader::ReadResponseBody()";
  EnterResource<PPB_URLLoader_API> enter(loader, callback, true);
  if (enter.failed())
    return enter.retval();
  return enter.SetResult(enter.object()->ReadResponseBody(buffer, bytes_to_read,
                                                          enter.callback()));
}

int32_t FinishStreamingToFile(PP_Resource loader,
                              struct PP_CompletionCallback callback) {
  VLOG(4) << "PPB_URLLoader::FinishStreamingToFile()";
  EnterResource<PPB_URLLoader_API> enter(loader, callback, true);
  if (enter.failed())
    return enter.retval();
  return enter.SetResult(
      enter.object()->FinishStreamingToFile(enter.callback()));
}

void Close(PP_Resource loader) {
  VLOG(4) << "PPB_URLLoader::Close()";
  EnterResource<PPB_URLLoader_API> enter(loader, true);
  if (enter.failed())
    return;
  enter.object()->Close();
}

const PPB_URLLoader_1_0 g_ppb_urlloader_thunk_1_0 = {&Create,
                                                     &IsURLLoader,
                                                     &Open,
                                                     &FollowRedirect,
                                                     &GetUploadProgress,
                                                     &GetDownloadProgress,
                                                     &GetResponseInfo,
                                                     &ReadResponseBody,
                                                     &FinishStreamingToFile,
                                                     &Close};

}  // namespace

PPAPI_THUNK_EXPORT const PPB_URLLoader_1_0* GetPPB_URLLoader_1_0_Thunk() {
  return &g_ppb_urlloader_thunk_1_0;
}

}  // namespace thunk
}  // namespace ppapi
