// 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 <stddef.h>
#include <stdint.h>

#include "base/compiler_specific.h"
#include "base/macros.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(), 0);
}

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) {
  }

  ~TestResource() override {}

  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
