// 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.

// This example shows how to use the URLLoader in "stream to file" mode where
// the browser writes incoming data to a file, which you can read out via the
// file I/O APIs.
//
// This example uses PostMessage between the plugin and the url_loader.html
// page in this directory to start the load and to communicate the result.

#include <stdint.h>

#include "ppapi/c/ppb_file_io.h"
#include "ppapi/cpp/file_io.h"
#include "ppapi/cpp/file_ref.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.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"

// When compiling natively on Windows, PostMessage can be #define-d to
// something else.
#ifdef PostMessage
#undef PostMessage
#endif

// Buffer size for reading network data.
const int kBufSize = 1024;

class MyInstance : public pp::Instance {
 public:
  explicit MyInstance(PP_Instance instance)
      : pp::Instance(instance) {
    factory_.Initialize(this);
  }
  virtual ~MyInstance() {
    // Make sure to explicitly close the loader. If somebody else is holding a
    // reference to the URLLoader object when this class goes out of scope (so
    // the URLLoader outlives "this"), and you have an outstanding read
    // request, the URLLoader will write into invalid memory.
    loader_.Close();
  }

  // Handler for the page sending us messages.
  virtual void HandleMessage(const pp::Var& message_data);

 private:
  // Called to initiate the request.
  void StartRequest(const std::string& url);

  // Callback for the URLLoader to tell us it finished opening the connection.
  void OnOpenComplete(int32_t result);

  // Callback for when the file is completely filled with the download
  void OnStreamComplete(int32_t result);

  void OnOpenFileComplete(int32_t result);
  void OnReadComplete(int32_t result);

  // Forwards the given string to the page.
  void ReportResponse(const std::string& data);

  // Generates completion callbacks scoped to this class.
  pp::CompletionCallbackFactory<MyInstance> factory_;

  pp::URLLoader loader_;
  pp::URLResponseInfo response_;
  pp::FileRef dest_file_;
  pp::FileIO file_io_;

  // The buffer used for the current read request. This is filled and then
  // copied into content_ to build up the entire document.
  char buf_[kBufSize];

  // All the content loaded so far.
  std::string content_;
};

void MyInstance::HandleMessage(const pp::Var& message_data) {
  if (message_data.is_string() && message_data.AsString() == "go")
    StartRequest("./fetched_content.html");
}

void MyInstance::StartRequest(const std::string& url) {
  content_.clear();

  pp::URLRequestInfo request(this);
  request.SetURL(url);
  request.SetMethod("GET");
  request.SetStreamToFile(true);

  loader_ = pp::URLLoader(this);
  loader_.Open(request,
               factory_.NewCallback(&MyInstance::OnOpenComplete));
}

void MyInstance::OnOpenComplete(int32_t result) {
  if (result != PP_OK) {
    ReportResponse("URL could not be requested");
    return;
  }

  loader_.FinishStreamingToFile(
      factory_.NewCallback(&MyInstance::OnStreamComplete));
  response_ = loader_.GetResponseInfo();
  dest_file_ = response_.GetBodyAsFileRef();
}

void MyInstance::OnStreamComplete(int32_t result) {
  if (result == PP_OK) {
    file_io_ = pp::FileIO(this);
    file_io_.Open(dest_file_, PP_FILEOPENFLAG_READ,
        factory_.NewCallback(&MyInstance::OnOpenFileComplete));
  } else {
    ReportResponse("Could not stream to file");
  }
}

void MyInstance::OnOpenFileComplete(int32_t result) {
  if (result == PP_OK) {
    // Note we only read the first 1024 bytes from the file in this example
    // to keep things simple. Please see a file I/O example for more details
    // on reading files.
    file_io_.Read(0, buf_, kBufSize,
        factory_.NewCallback(&MyInstance::OnReadComplete));
  } else {
    ReportResponse("Could not open file");
  }
}

void MyInstance::OnReadComplete(int32_t result) {
  if (result >= 0) {
    content_.append(buf_, result);
    ReportResponse(buf_);
  } else {
    ReportResponse("Could not read file");
  }

  // Release everything.
  loader_ = pp::URLLoader();
  response_ = pp::URLResponseInfo();
  dest_file_ = pp::FileRef();
  file_io_ = pp::FileIO();
}

void MyInstance::ReportResponse(const std::string& data) {
  PostMessage(pp::Var(data));
}

// This object is the global object representing this plugin library as long
// as it is loaded.
class MyModule : public pp::Module {
 public:
  MyModule() : pp::Module() {}
  virtual ~MyModule() {}

  // Override CreateInstance to create your customized Instance object.
  virtual pp::Instance* CreateInstance(PP_Instance instance) {
    return new MyInstance(instance);
  }
};

namespace pp {

// Factory function for your specialization of the Module object.
Module* CreateModule() {
  return new MyModule();
}

}  // namespace pp
