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

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/proxy/connection.h"
#include "ppapi/proxy/device_enumeration_resource_helper.h"
#include "ppapi/proxy/plugin_message_filter.h"
#include "ppapi/proxy/plugin_resource.h"
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/proxy/plugin_var_tracker.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/ppb_device_ref_shared.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_device_ref_api.h"
#include "ppapi/thunk/thunk.h"

namespace ppapi {
namespace proxy {

namespace {

typedef PluginProxyTest DeviceEnumerationResourceHelperTest;

Connection GetConnection(PluginProxyTestHarness* harness) {
  CHECK(harness->GetGlobals()->IsPluginGlobals());

  return Connection(
      static_cast<PluginGlobals*>(harness->GetGlobals())->GetBrowserSender(),
      harness->plugin_dispatcher());
}

bool CompareDeviceRef(PluginVarTracker* var_tracker,
                      PP_Resource resource,
                      const DeviceRefData& expected) {
  thunk::EnterResourceNoLock<thunk::PPB_DeviceRef_API> enter(resource, true);
  if (enter.failed())
    return false;

  if (expected.type != enter.object()->GetType())
    return false;

  PP_Var name_pp_var = enter.object()->GetName();
  bool result = false;
  do {
    Var* name_var = var_tracker->GetVar(name_pp_var);
    if (!name_var)
      break;
    StringVar* name_string_var = name_var->AsStringVar();
    if (!name_string_var)
      break;
    if (expected.name != name_string_var->value())
      break;

    result = true;
  } while (false);
  var_tracker->ReleaseVar(name_pp_var);
  return result;
}

class TestResource : public PluginResource {
 public:
  TestResource(Connection connection, PP_Instance instance)
      : PluginResource(connection, instance),
        device_enumeration_(this) {
  }

  virtual ~TestResource() {}

  virtual void OnReplyReceived(const ResourceMessageReplyParams& params,
                               const IPC::Message& msg) override {
    if (!device_enumeration_.HandleReply(params, msg))
      PluginResource::OnReplyReceived(params, msg);
  }

  DeviceEnumerationResourceHelper& device_enumeration() {
    return device_enumeration_;
  }

 private:
  DeviceEnumerationResourceHelper device_enumeration_;

  DISALLOW_COPY_AND_ASSIGN(TestResource);
};

class TestCallback {
 public:
  TestCallback() : called_(false), result_(PP_ERROR_FAILED) {
  }
  ~TestCallback() {
    CHECK(called_);
  }

  PP_CompletionCallback MakeCompletionCallback() {
    return PP_MakeCompletionCallback(&CompletionCallbackBody, this);
  }

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

 private:
  static void CompletionCallbackBody(void* user_data, int32_t result) {
    TestCallback* callback = static_cast<TestCallback*>(user_data);

    CHECK(!callback->called_);
    callback->called_ = true;
    callback->result_ = result;
  }

  bool called_;
  int32_t result_;

  DISALLOW_COPY_AND_ASSIGN(TestCallback);
};

class TestArrayOutput {
 public:
  explicit TestArrayOutput(PluginResourceTracker* resource_tracker)
      : data_(NULL),
        count_(0),
        resource_tracker_(resource_tracker) {
  }

  ~TestArrayOutput() {
    if (count_ > 0) {
      for (size_t i = 0; i < count_; ++i)
        resource_tracker_->ReleaseResource(data_[i]);
      delete [] data_;
    }
  }

  PP_ArrayOutput MakeArrayOutput() {
    PP_ArrayOutput array_output = { &GetDataBuffer, this };
    return array_output;
  }

  const PP_Resource* data() const { return data_; }
  uint32_t count() const { return count_; }

 private:
  static void* GetDataBuffer(void* user_data,
                             uint32_t element_count,
                             uint32_t element_size) {
    CHECK_EQ(element_size, sizeof(PP_Resource));

    TestArrayOutput* output = static_cast<TestArrayOutput*>(user_data);
    CHECK(!output->data_);

    output->count_ = element_count;
    if (element_count > 0)
      output->data_ = new PP_Resource[element_count];
    else
      output->data_ = NULL;

    return output->data_;
  }

  PP_Resource* data_;
  uint32_t count_;
  PluginResourceTracker* resource_tracker_;

  DISALLOW_COPY_AND_ASSIGN(TestArrayOutput);
};

class TestMonitorDeviceChange {
 public:
  explicit TestMonitorDeviceChange(PluginVarTracker* var_tracker)
      : called_(false),
        same_as_expected_(false),
        var_tracker_(var_tracker) {
  }

  ~TestMonitorDeviceChange() {}

  void SetExpectedResult(const std::vector<DeviceRefData>& expected) {
    called_ = false;
    same_as_expected_ = false;
    expected_ = expected;
  }

  bool called() const { return called_; }

  bool same_as_expected() const { return same_as_expected_; }

  static void MonitorDeviceChangeCallback(void* user_data,
                                          uint32_t device_count,
                                          const PP_Resource devices[]) {
    ProxyAutoLock lock;
    TestMonitorDeviceChange* helper =
        static_cast<TestMonitorDeviceChange*>(user_data);
    CHECK(!helper->called_);

    helper->called_ = true;
    helper->same_as_expected_ = false;
    if (device_count != helper->expected_.size())
      return;
    for (size_t i = 0; i < device_count; ++i) {
      if (!CompareDeviceRef(helper->var_tracker_, devices[i],
                            helper->expected_[i])) {
        return;
      }
    }
    helper->same_as_expected_ = true;
  }

 private:
  bool called_;
  bool same_as_expected_;
  std::vector<DeviceRefData> expected_;
  PluginVarTracker* var_tracker_;

  DISALLOW_COPY_AND_ASSIGN(TestMonitorDeviceChange);
};

}  // namespace

TEST_F(DeviceEnumerationResourceHelperTest, EnumerateDevices) {
  ProxyAutoLock lock;

  scoped_refptr<TestResource> resource(
      new TestResource(GetConnection(this), pp_instance()));
  DeviceEnumerationResourceHelper& device_enumeration =
      resource->device_enumeration();

  TestArrayOutput output(&resource_tracker());
  TestCallback callback;
  scoped_refptr<TrackedCallback> tracked_callback(
      new TrackedCallback(resource.get(), callback.MakeCompletionCallback()));
  int32_t result = device_enumeration.EnumerateDevices(output.MakeArrayOutput(),
                                                       tracked_callback);
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

  // Should have sent an EnumerateDevices message.
  ResourceMessageCallParams params;
  IPC::Message msg;
  ASSERT_TRUE(sink().GetFirstResourceCallMatching(
      PpapiHostMsg_DeviceEnumeration_EnumerateDevices::ID, &params, &msg));

  // Synthesize a response.
  ResourceMessageReplyParams reply_params(params.pp_resource(),
                                          params.sequence());
  reply_params.set_result(PP_OK);
  std::vector<DeviceRefData> data;
  DeviceRefData data_item;
  data_item.type = PP_DEVICETYPE_DEV_AUDIOCAPTURE;
  data_item.name = "name_1";
  data_item.id = "id_1";
  data.push_back(data_item);
  data_item.type = PP_DEVICETYPE_DEV_VIDEOCAPTURE;
  data_item.name = "name_2";
  data_item.id = "id_2";
  data.push_back(data_item);

  {
    ProxyAutoUnlock unlock;
    PluginMessageFilter::DispatchResourceReplyForTest(
        reply_params,
        PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply(data));
  }
  EXPECT_TRUE(callback.called());
  EXPECT_EQ(PP_OK, callback.result());
  EXPECT_EQ(2U, output.count());
  for (size_t i = 0; i < output.count(); ++i)
    EXPECT_TRUE(CompareDeviceRef(&var_tracker(), output.data()[i], data[i]));
}

TEST_F(DeviceEnumerationResourceHelperTest, MonitorDeviceChange) {
  ProxyAutoLock lock;

  scoped_refptr<TestResource> resource(
      new TestResource(GetConnection(this), pp_instance()));
  DeviceEnumerationResourceHelper& device_enumeration =
      resource->device_enumeration();

  TestMonitorDeviceChange helper(&var_tracker());

  int32_t result = device_enumeration.MonitorDeviceChange(
      &TestMonitorDeviceChange::MonitorDeviceChangeCallback, &helper);
  ASSERT_EQ(PP_OK, result);

  // Should have sent a MonitorDeviceChange message.
  ResourceMessageCallParams params;
  IPC::Message msg;
  ASSERT_TRUE(sink().GetFirstResourceCallMatching(
      PpapiHostMsg_DeviceEnumeration_MonitorDeviceChange::ID, &params, &msg));
  sink().ClearMessages();

  uint32_t callback_id = 0;
  ASSERT_TRUE(UnpackMessage<PpapiHostMsg_DeviceEnumeration_MonitorDeviceChange>(
      msg, &callback_id));

  ResourceMessageReplyParams reply_params(params.pp_resource(), 0);
  reply_params.set_result(PP_OK);
  std::vector<DeviceRefData> data;

  helper.SetExpectedResult(data);

  {
    ProxyAutoUnlock unlock;
    // Synthesize a response with no device.
    PluginMessageFilter::DispatchResourceReplyForTest(
        reply_params,
        PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange(
            callback_id, data));
  }
  EXPECT_TRUE(helper.called() && helper.same_as_expected());

  DeviceRefData data_item;
  data_item.type = PP_DEVICETYPE_DEV_AUDIOCAPTURE;
  data_item.name = "name_1";
  data_item.id = "id_1";
  data.push_back(data_item);
  data_item.type = PP_DEVICETYPE_DEV_VIDEOCAPTURE;
  data_item.name = "name_2";
  data_item.id = "id_2";
  data.push_back(data_item);

  helper.SetExpectedResult(data);

  {
    ProxyAutoUnlock unlock;
    // Synthesize a response with some devices.
    PluginMessageFilter::DispatchResourceReplyForTest(
        reply_params,
        PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange(
            callback_id, data));
  }
  EXPECT_TRUE(helper.called() && helper.same_as_expected());

  TestMonitorDeviceChange helper2(&var_tracker());

  result = device_enumeration.MonitorDeviceChange(
      &TestMonitorDeviceChange::MonitorDeviceChangeCallback, &helper2);
  ASSERT_EQ(PP_OK, result);

  // Should have sent another MonitorDeviceChange message.
  ResourceMessageCallParams params2;
  IPC::Message msg2;
  ASSERT_TRUE(sink().GetFirstResourceCallMatching(
      PpapiHostMsg_DeviceEnumeration_MonitorDeviceChange::ID, &params2, &msg2));
  sink().ClearMessages();

  uint32_t callback_id2 = 0;
  ASSERT_TRUE(UnpackMessage<PpapiHostMsg_DeviceEnumeration_MonitorDeviceChange>(
      msg2, &callback_id2));

  helper.SetExpectedResult(data);
  helper2.SetExpectedResult(data);
  {
    ProxyAutoUnlock unlock;
    // |helper2| should receive the result while |helper| shouldn't.
    PluginMessageFilter::DispatchResourceReplyForTest(
        reply_params,
        PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange(
            callback_id2, data));
  }
  EXPECT_TRUE(helper2.called() && helper2.same_as_expected());
  EXPECT_FALSE(helper.called());

  helper.SetExpectedResult(data);
  helper2.SetExpectedResult(data);
  {
    ProxyAutoUnlock unlock;
    // Even if a message with |callback_id| arrives. |helper| shouldn't receive
    // the result.
    PluginMessageFilter::DispatchResourceReplyForTest(
        reply_params,
        PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange(
            callback_id, data));
  }
  EXPECT_FALSE(helper2.called());
  EXPECT_FALSE(helper.called());

  result = device_enumeration.MonitorDeviceChange(NULL, NULL);
  ASSERT_EQ(PP_OK, result);

  // Should have sent a StopMonitoringDeviceChange message.
  ResourceMessageCallParams params3;
  IPC::Message msg3;
  ASSERT_TRUE(sink().GetFirstResourceCallMatching(
      PpapiHostMsg_DeviceEnumeration_StopMonitoringDeviceChange::ID,
      &params3, &msg3));
  sink().ClearMessages();

  helper2.SetExpectedResult(data);
  {
    ProxyAutoUnlock unlock;
    // |helper2| shouldn't receive any result any more.
    PluginMessageFilter::DispatchResourceReplyForTest(
        reply_params,
        PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange(
            callback_id2, data));
  }
  EXPECT_FALSE(helper2.called());
}

}  // namespace proxy
}  // namespace ppapi
