// Copyright 2014 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 <stdint.h>

#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_file_io.h"
#include "ppapi/c/ppb_file_ref.h"
#include "ppapi/c/ppb_file_system.h"
#include "ppapi/proxy/file_system_resource.h"
#include "ppapi/proxy/locking_resource_releaser.h"
#include "ppapi/proxy/plugin_message_filter.h"
#include "ppapi/proxy/ppapi_message_utils.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppapi_proxy_test.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/scoped_pp_var.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_file_system_api.h"
#include "ppapi/thunk/thunk.h"

using ppapi::proxy::ResourceMessageTestSink;
using ppapi::thunk::EnterResource;
using ppapi::thunk::PPB_FileSystem_API;

namespace ppapi {
namespace proxy {

namespace {

const int64_t kExpectedFileSystemSize = 100;
const int64_t kQuotaRequestAmount1 = 10;
const int64_t kQuotaRequestAmount2 = 20;

class MockCompletionCallback {
 public:
  MockCompletionCallback() : called_(false) {}

  bool called() { return called_; }
  int32_t result() { return result_; }

  static void Callback(void* user_data, int32_t result) {
    MockCompletionCallback* that =
        reinterpret_cast<MockCompletionCallback*>(user_data);
    that->called_ = true;
    that->result_ = result;
  }

 private:
  bool called_;
  int32_t result_;
};

class MockRequestQuotaCallback {
 public:
  MockRequestQuotaCallback() : called_(false) {}

  bool called() { return called_; }
  int64_t result() { return result_; }

  void Reset() { called_ = false; }

  void Callback(int64_t result) {
    ASSERT_FALSE(called_);
    called_ = true;
    result_ = result;
  }

 private:
  bool called_;
  int64_t result_;
};

class FileSystemResourceTest : public PluginProxyTest {
 public:
  const PPB_FileSystem_1_0* file_system_iface;
  const PPB_FileRef_1_1* file_ref_iface;
  const PPB_FileIO_1_1* file_io_iface;

  FileSystemResourceTest()
      : file_system_iface(thunk::GetPPB_FileSystem_1_0_Thunk()),
        file_ref_iface(thunk::GetPPB_FileRef_1_1_Thunk()),
        file_io_iface(thunk::GetPPB_FileIO_1_1_Thunk()) {
  }

  void SendReply(const ResourceMessageCallParams& params,
                 int32_t result,
                 const IPC::Message& nested_message) {
    ResourceMessageReplyParams reply_params(params.pp_resource(),
                                            params.sequence());
    reply_params.set_result(result);
    PluginMessageFilter::DispatchResourceReplyForTest(
        reply_params, nested_message);
  }

  void SendOpenReply(const ResourceMessageCallParams& params, int32_t result) {
    SendReply(params, result, PpapiPluginMsg_FileSystem_OpenReply());
  }

  // Opens the given file system.
  void OpenFileSystem(PP_Resource file_system) {
    MockCompletionCallback cb;
    int32_t result = file_system_iface->Open(
        file_system,
        kExpectedFileSystemSize,
        PP_MakeCompletionCallback(&MockCompletionCallback::Callback, &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

    // Should have sent two new "open" messages to the browser and renderer.
    ResourceMessageTestSink::ResourceCallVector open_messages =
        sink().GetAllResourceCallsMatching(PpapiHostMsg_FileSystem_Open::ID);
    ASSERT_EQ(2U, open_messages.size());
    sink().ClearMessages();

    // The resource is expecting two replies.
    SendOpenReply(open_messages[0].first, PP_OK);
    SendOpenReply(open_messages[1].first, PP_OK);

    ASSERT_TRUE(cb.called());
    ASSERT_EQ(PP_OK, cb.result());
  }

  // Opens the given file in the given file system. Since there is no host,
  // the file handle will be invalid.
  void OpenFile(PP_Resource file_io,
                PP_Resource file_ref,
                PP_Resource file_system) {
    MockCompletionCallback cb;
    int32_t result = file_io_iface->Open(
        file_io,
        file_ref,
        PP_FILEOPENFLAG_WRITE,
        PP_MakeCompletionCallback(&MockCompletionCallback::Callback, &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

    // Should have sent an "open" message.
    ResourceMessageCallParams params;
    IPC::Message msg;
    ASSERT_TRUE(sink().GetFirstResourceCallMatching(
        PpapiHostMsg_FileIO_Open::ID, &params, &msg));
    sink().ClearMessages();

    // Send a success reply.
    ResourceMessageReplyParams reply_params(params.pp_resource(),
                                            params.sequence());
    reply_params.set_result(PP_OK);
    PluginMessageFilter::DispatchResourceReplyForTest(
        reply_params,
        PpapiPluginMsg_FileIO_OpenReply(file_system,
                                        0 /* max_written_offset */));
  }
};

}  // namespace

// Test that Open fails if either host returns failure. The other tests exercise
// the case where both hosts return PP_OK.
TEST_F(FileSystemResourceTest, OpenFailure) {
  // Fail if the first reply doesn't return PP_OK.
  {
    LockingResourceReleaser file_system(
        file_system_iface->Create(pp_instance(),
                                  PP_FILESYSTEMTYPE_LOCALTEMPORARY));

    MockCompletionCallback cb;
    int32_t result = file_system_iface->Open(
        file_system.get(),
        kExpectedFileSystemSize,
        PP_MakeCompletionCallback(&MockCompletionCallback::Callback, &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

    ResourceMessageTestSink::ResourceCallVector open_messages =
        sink().GetAllResourceCallsMatching(PpapiHostMsg_FileSystem_Open::ID);
    ASSERT_EQ(2U, open_messages.size());
    sink().ClearMessages();

    SendOpenReply(open_messages[0].first, PP_ERROR_FAILED);
    SendOpenReply(open_messages[1].first, PP_OK);

    ASSERT_TRUE(cb.called());
    ASSERT_EQ(PP_ERROR_FAILED, cb.result());
  }
  // Fail if the second reply doesn't return PP_OK.
  {
    LockingResourceReleaser file_system(
        file_system_iface->Create(pp_instance(),
                                  PP_FILESYSTEMTYPE_LOCALTEMPORARY));

    MockCompletionCallback cb;
    int32_t result = file_system_iface->Open(
        file_system.get(),
        kExpectedFileSystemSize,
        PP_MakeCompletionCallback(&MockCompletionCallback::Callback, &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

    ResourceMessageTestSink::ResourceCallVector open_messages =
        sink().GetAllResourceCallsMatching(PpapiHostMsg_FileSystem_Open::ID);
    ASSERT_EQ(2U, open_messages.size());
    sink().ClearMessages();

    SendOpenReply(open_messages[0].first, PP_OK);
    SendOpenReply(open_messages[1].first, PP_ERROR_FAILED);

    ASSERT_TRUE(cb.called());
    ASSERT_EQ(PP_ERROR_FAILED, cb.result());
  }
}

TEST_F(FileSystemResourceTest, RequestQuota) {
  LockingResourceReleaser file_system(
      file_system_iface->Create(pp_instance(),
                                PP_FILESYSTEMTYPE_LOCALTEMPORARY));

  OpenFileSystem(file_system.get());

  // Create and open two files in the file system. FileIOResource calls
  // FileSystemResource::OpenQuotaFile on success.
  LockingResourceReleaser file_ref1(
      file_ref_iface->Create(file_system.get(), "/file1"));
  LockingResourceReleaser file_io1(file_io_iface->Create(pp_instance()));
  OpenFile(file_io1.get(), file_ref1.get(), file_system.get());
  LockingResourceReleaser file_ref2(
      file_ref_iface->Create(file_system.get(), "/file2"));
  LockingResourceReleaser file_io2(file_io_iface->Create(pp_instance()));
  OpenFile(file_io2.get(), file_ref2.get(), file_system.get());

  EnterResource<PPB_FileSystem_API> enter(file_system.get(), true);
  ASSERT_FALSE(enter.failed());
  PPB_FileSystem_API* file_system_api = enter.object();

  MockRequestQuotaCallback cb1;
  int64_t result = file_system_api->RequestQuota(
      kQuotaRequestAmount1,
      base::Bind(&MockRequestQuotaCallback::Callback, base::Unretained(&cb1)));
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

  // Should have sent a "reserve quota" message, with the amount of the request
  // and a map of all currently open files to their max written offsets.
  ResourceMessageCallParams params;
  IPC::Message msg;
  ASSERT_TRUE(sink().GetFirstResourceCallMatching(
      PpapiHostMsg_FileSystem_ReserveQuota::ID, &params, &msg));
  sink().ClearMessages();

  int64_t amount = 0;
  FileGrowthMap file_growths;
  ASSERT_TRUE(UnpackMessage<PpapiHostMsg_FileSystem_ReserveQuota>(
      msg, &amount, &file_growths));
  ASSERT_EQ(kQuotaRequestAmount1, amount);
  ASSERT_EQ(2U, file_growths.size());
  ASSERT_EQ(0, file_growths[file_io1.get()].max_written_offset);
  ASSERT_EQ(0, file_growths[file_io2.get()].max_written_offset);

  // Make another request while the "reserve quota" message is pending.
  MockRequestQuotaCallback cb2;
  result = file_system_api->RequestQuota(
      kQuotaRequestAmount2,
      base::Bind(&MockRequestQuotaCallback::Callback, base::Unretained(&cb2)));
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  // No new "reserve quota" message should be sent while one is pending.
  ASSERT_FALSE(sink().GetFirstResourceCallMatching(
      PpapiHostMsg_FileSystem_ReserveQuota::ID, &params, &msg));
  {
    ProxyAutoUnlock unlock_to_prevent_deadlock;
    // Reply with quota reservation amount sufficient to cover both requests.
    // Both callbacks should be called with the requests granted.
    SendReply(params,
              PP_OK,
              PpapiPluginMsg_FileSystem_ReserveQuotaReply(
                  kQuotaRequestAmount1 + kQuotaRequestAmount2,
                  FileGrowthMapToFileSizeMapForTesting(file_growths)));
  }
  ASSERT_TRUE(cb1.called());
  ASSERT_EQ(kQuotaRequestAmount1, cb1.result());
  ASSERT_TRUE(cb2.called());
  ASSERT_EQ(kQuotaRequestAmount2, cb2.result());
  cb1.Reset();
  cb2.Reset();

  // All requests should fail when insufficient quota is returned to satisfy
  // the first request.
  result = file_system_api->RequestQuota(
      kQuotaRequestAmount1,
      base::Bind(&MockRequestQuotaCallback::Callback, base::Unretained(&cb1)));
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  result = file_system_api->RequestQuota(
      kQuotaRequestAmount2,
      base::Bind(&MockRequestQuotaCallback::Callback, base::Unretained(&cb2)));
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

  ASSERT_TRUE(sink().GetFirstResourceCallMatching(
      PpapiHostMsg_FileSystem_ReserveQuota::ID, &params, &msg));
  sink().ClearMessages();
  {
    ProxyAutoUnlock unlock_to_prevent_deadlock;
    // Reply with quota reservation amount insufficient to cover the first
    // request.
    SendReply(params,
              PP_OK,
              PpapiPluginMsg_FileSystem_ReserveQuotaReply(
                  kQuotaRequestAmount1 - 1,
                  FileGrowthMapToFileSizeMapForTesting(file_growths)));
  }
  ASSERT_TRUE(cb1.called());
  ASSERT_EQ(0, cb1.result());
  ASSERT_TRUE(cb2.called());
  ASSERT_EQ(0, cb2.result());
  cb1.Reset();
  cb2.Reset();

  // A new request should be made if the quota reservation is enough to satisfy
  // at least one request.
  result = file_system_api->RequestQuota(
      kQuotaRequestAmount1,
      base::Bind(&MockRequestQuotaCallback::Callback, base::Unretained(&cb1)));
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  result = file_system_api->RequestQuota(
      kQuotaRequestAmount2,
      base::Bind(&MockRequestQuotaCallback::Callback, base::Unretained(&cb2)));
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

  ASSERT_TRUE(sink().GetFirstResourceCallMatching(
      PpapiHostMsg_FileSystem_ReserveQuota::ID, &params, &msg));
  sink().ClearMessages();
  {
    ProxyAutoUnlock unlock_to_prevent_deadlock;
    // Reply with quota reservation amount sufficient only to cover the first
    // request.
    SendReply(params,
              PP_OK,
              PpapiPluginMsg_FileSystem_ReserveQuotaReply(
                  kQuotaRequestAmount1,
                  FileGrowthMapToFileSizeMapForTesting(file_growths)));
  }
  ASSERT_TRUE(cb1.called());
  ASSERT_EQ(kQuotaRequestAmount1, cb1.result());
  ASSERT_FALSE(cb2.called());

  // Another request message should have been sent.
  ASSERT_TRUE(sink().GetFirstResourceCallMatching(
      PpapiHostMsg_FileSystem_ReserveQuota::ID, &params, &msg));
  sink().ClearMessages();
  {
    ProxyAutoUnlock unlock_to_prevent_deadlock;
    // Reply with quota reservation amount sufficient to cover the second
    // request and some extra.
    SendReply(params,
              PP_OK,
              PpapiPluginMsg_FileSystem_ReserveQuotaReply(
                  kQuotaRequestAmount1 + kQuotaRequestAmount2,
                  FileGrowthMapToFileSizeMapForTesting(file_growths)));
  }

  ASSERT_TRUE(cb2.called());
  ASSERT_EQ(kQuotaRequestAmount2, cb2.result());
  cb1.Reset();
  cb2.Reset();

  // There is kQuotaRequestAmount1 of quota left, and a request for it should
  // succeed immediately.
  result = file_system_api->RequestQuota(
      kQuotaRequestAmount1,
      base::Bind(&MockRequestQuotaCallback::Callback, base::Unretained(&cb1)));
  ASSERT_EQ(kQuotaRequestAmount1, result);
}

}  // namespace proxy
}  // namespace ppapi
