// 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/bind.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/shared_impl/callback_tracker.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/resource.h"
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/shared_impl/test_globals.h"
#include "ppapi/shared_impl/tracked_callback.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ppapi {

namespace {

class TrackedCallbackTest : public testing::Test {
 public:
  TrackedCallbackTest()
      : message_loop_(base::MessageLoop::TYPE_DEFAULT), pp_instance_(1234) {}

  PP_Instance pp_instance() const { return pp_instance_; }

  virtual void SetUp() OVERRIDE {
    ProxyLock::EnableLockingOnThreadForTest();
    ProxyAutoLock lock;
    globals_.GetResourceTracker()->DidCreateInstance(pp_instance_);
  }
  virtual void TearDown() OVERRIDE {
    ProxyAutoLock lock;
    globals_.GetResourceTracker()->DidDeleteInstance(pp_instance_);
  }

 private:
  base::MessageLoop message_loop_;
  TestGlobals globals_;
  PP_Instance pp_instance_;
};

// All valid results (PP_OK, PP_ERROR_...) are nonpositive.
const int32_t kInitializedResultValue = 1;
const int32_t kOverrideResultValue = 2;

struct CallbackRunInfo {
  CallbackRunInfo()
      : run_count(0),
        result(kInitializedResultValue),
        completion_task_run_count(0),
        completion_task_result(kInitializedResultValue) {}
  unsigned run_count;
  int32_t result;
  unsigned completion_task_run_count;
  int32_t completion_task_result;
};

void TestCallback(void* user_data, int32_t result) {
  CallbackRunInfo* info = reinterpret_cast<CallbackRunInfo*>(user_data);
  info->run_count++;
  if (info->run_count == 1)
    info->result = result;
}

}  // namespace

// CallbackShutdownTest --------------------------------------------------------

namespace {

class CallbackShutdownTest : public TrackedCallbackTest {
 public:
  CallbackShutdownTest() {}

  // Cases:
  // (1) A callback which is run (so shouldn't be aborted on shutdown).
  // (2) A callback which is aborted (so shouldn't be aborted on shutdown).
  // (3) A callback which isn't run (so should be aborted on shutdown).
  CallbackRunInfo& info_did_run() { return info_did_run_; }  // (1)
  CallbackRunInfo& info_did_abort() { return info_did_abort_; }  // (2)
  CallbackRunInfo& info_didnt_run() { return info_didnt_run_; }  // (3)

 private:
  CallbackRunInfo info_did_run_;
  CallbackRunInfo info_did_abort_;
  CallbackRunInfo info_didnt_run_;
};

}  // namespace

// Tests that callbacks are properly aborted on module shutdown.
TEST_F(CallbackShutdownTest, AbortOnShutdown) {
  ProxyAutoLock lock;
  scoped_refptr<Resource> resource(new Resource(OBJECT_IS_IMPL, pp_instance()));

  // Set up case (1) (see above).
  EXPECT_EQ(0U, info_did_run().run_count);
  scoped_refptr<TrackedCallback> callback_did_run = new TrackedCallback(
      resource.get(),
      PP_MakeCompletionCallback(&TestCallback, &info_did_run()));
  EXPECT_EQ(0U, info_did_run().run_count);
  callback_did_run->Run(PP_OK);
  EXPECT_EQ(1U, info_did_run().run_count);
  EXPECT_EQ(PP_OK, info_did_run().result);

  // Set up case (2).
  EXPECT_EQ(0U, info_did_abort().run_count);
  scoped_refptr<TrackedCallback> callback_did_abort = new TrackedCallback(
      resource.get(),
      PP_MakeCompletionCallback(&TestCallback, &info_did_abort()));
  EXPECT_EQ(0U, info_did_abort().run_count);
  callback_did_abort->Abort();
  EXPECT_EQ(1U, info_did_abort().run_count);
  EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort().result);

  // Set up case (3).
  EXPECT_EQ(0U, info_didnt_run().run_count);
  scoped_refptr<TrackedCallback> callback_didnt_run = new TrackedCallback(
      resource.get(),
      PP_MakeCompletionCallback(&TestCallback, &info_didnt_run()));
  EXPECT_EQ(0U, info_didnt_run().run_count);

  PpapiGlobals::Get()->GetCallbackTrackerForInstance(pp_instance())->AbortAll();

  // Check case (1).
  EXPECT_EQ(1U, info_did_run().run_count);

  // Check case (2).
  EXPECT_EQ(1U, info_did_abort().run_count);

  // Check case (3).
  EXPECT_EQ(1U, info_didnt_run().run_count);
  EXPECT_EQ(PP_ERROR_ABORTED, info_didnt_run().result);
}

// CallbackResourceTest --------------------------------------------------------

namespace {

class CallbackResourceTest : public TrackedCallbackTest {
 public:
  CallbackResourceTest() {}
};

class CallbackMockResource : public Resource {
 public:
  CallbackMockResource(PP_Instance instance)
      : Resource(OBJECT_IS_IMPL, instance) {}
  ~CallbackMockResource() {}

  PP_Resource SetupForTest() {
    PP_Resource resource_id = GetReference();
    EXPECT_NE(0, resource_id);

    callback_did_run_ = new TrackedCallback(
        this,
        PP_MakeCompletionCallback(&TestCallback, &info_did_run_));
    EXPECT_EQ(0U, info_did_run_.run_count);
    EXPECT_EQ(0U, info_did_run_.completion_task_run_count);

    // In order to test that the completion task can override the callback
    // result, we need to test callbacks with and without a completion task.
    callback_did_run_with_completion_task_ = new TrackedCallback(
        this,
        PP_MakeCompletionCallback(&TestCallback,
                                  &info_did_run_with_completion_task_));
    callback_did_run_with_completion_task_->set_completion_task(
        Bind(&CallbackMockResource::CompletionTask, this,
             &info_did_run_with_completion_task_));
    EXPECT_EQ(0U, info_did_run_with_completion_task_.run_count);
    EXPECT_EQ(0U, info_did_run_with_completion_task_.completion_task_run_count);

    callback_did_abort_ = new TrackedCallback(
        this,
        PP_MakeCompletionCallback(&TestCallback, &info_did_abort_));
    callback_did_abort_->set_completion_task(
        Bind(&CallbackMockResource::CompletionTask, this, &info_did_abort_));
    EXPECT_EQ(0U, info_did_abort_.run_count);
    EXPECT_EQ(0U, info_did_abort_.completion_task_run_count);

    callback_didnt_run_ = new TrackedCallback(
        this,
        PP_MakeCompletionCallback(&TestCallback, &info_didnt_run_));
    callback_didnt_run_->set_completion_task(
        Bind(&CallbackMockResource::CompletionTask, this, &info_didnt_run_));
    EXPECT_EQ(0U, info_didnt_run_.run_count);
    EXPECT_EQ(0U, info_didnt_run_.completion_task_run_count);

    callback_did_run_->Run(PP_OK);
    callback_did_run_with_completion_task_->Run(PP_OK);
    callback_did_abort_->Abort();

    CheckIntermediateState();

    return resource_id;
  }

  int32_t CompletionTask(CallbackRunInfo* info, int32_t result) {
    // We should run before the callback.
    EXPECT_EQ(0U, info->run_count);
    info->completion_task_run_count++;
    if (info->completion_task_run_count == 1)
      info->completion_task_result = result;
    return kOverrideResultValue;
  }

  void CheckIntermediateState() {
    EXPECT_EQ(1U, info_did_run_.run_count);
    EXPECT_EQ(PP_OK, info_did_run_.result);
    EXPECT_EQ(0U, info_did_run_.completion_task_run_count);

    EXPECT_EQ(1U, info_did_run_with_completion_task_.run_count);
    // completion task should override the result.
    EXPECT_EQ(kOverrideResultValue, info_did_run_with_completion_task_.result);
    EXPECT_EQ(1U, info_did_run_with_completion_task_.completion_task_run_count);
    EXPECT_EQ(PP_OK,
              info_did_run_with_completion_task_.completion_task_result);

    EXPECT_EQ(1U, info_did_abort_.run_count);
    // completion task shouldn't override an abort.
    EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort_.result);
    EXPECT_EQ(1U, info_did_abort_.completion_task_run_count);
    EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort_.completion_task_result);

    EXPECT_EQ(0U, info_didnt_run_.completion_task_run_count);
    EXPECT_EQ(0U, info_didnt_run_.run_count);
  }

  void CheckFinalState() {
    EXPECT_EQ(1U, info_did_run_.run_count);
    EXPECT_EQ(PP_OK, info_did_run_.result);
    EXPECT_EQ(1U, info_did_abort_.run_count);
    EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort_.result);
    EXPECT_EQ(1U, info_didnt_run_.run_count);
    EXPECT_EQ(PP_ERROR_ABORTED, info_didnt_run_.result);
  }

  scoped_refptr<TrackedCallback> callback_did_run_;
  CallbackRunInfo info_did_run_;

  scoped_refptr<TrackedCallback> callback_did_run_with_completion_task_;
  CallbackRunInfo info_did_run_with_completion_task_;

  scoped_refptr<TrackedCallback> callback_did_abort_;
  CallbackRunInfo info_did_abort_;

  scoped_refptr<TrackedCallback> callback_didnt_run_;
  CallbackRunInfo info_didnt_run_;
};

}  // namespace

// Test that callbacks get aborted on the last resource unref.
TEST_F(CallbackResourceTest, AbortOnNoRef) {
  ProxyAutoLock lock;
  ResourceTracker* resource_tracker =
      PpapiGlobals::Get()->GetResourceTracker();

  // Test several things: Unref-ing a resource (to zero refs) with callbacks
  // which (1) have been run, (2) have been aborted, (3) haven't been completed.
  // Check that the uncompleted one gets aborted, and that the others don't get
  // called again.
  scoped_refptr<CallbackMockResource> resource_1(
      new CallbackMockResource(pp_instance()));
  PP_Resource resource_1_id = resource_1->SetupForTest();

  // Also do the same for a second resource, and make sure that unref-ing the
  // first resource doesn't much up the second resource.
  scoped_refptr<CallbackMockResource> resource_2(
      new CallbackMockResource(pp_instance()));
  PP_Resource resource_2_id = resource_2->SetupForTest();

  // Double-check that resource #1 is still okay.
  resource_1->CheckIntermediateState();

  // Kill resource #1, spin the message loop to run posted calls, and check that
  // things are in the expected states.
  resource_tracker->ReleaseResource(resource_1_id);
  {
    ProxyAutoUnlock unlock;
    base::MessageLoop::current()->RunUntilIdle();
  }
  resource_1->CheckFinalState();
  resource_2->CheckIntermediateState();

  // Kill resource #2.
  resource_tracker->ReleaseResource(resource_2_id);
  {
    ProxyAutoUnlock unlock;
    base::MessageLoop::current()->RunUntilIdle();
  }
  resource_1->CheckFinalState();
  resource_2->CheckFinalState();

  // This shouldn't be needed, but make sure there are no stranded tasks.
  {
    ProxyAutoUnlock unlock;
    base::MessageLoop::current()->RunUntilIdle();
  }
}

// Test that "resurrecting" a resource (getting a new ID for a |Resource|)
// doesn't resurrect callbacks.
TEST_F(CallbackResourceTest, Resurrection) {
  ProxyAutoLock lock;
  ResourceTracker* resource_tracker =
      PpapiGlobals::Get()->GetResourceTracker();

  scoped_refptr<CallbackMockResource> resource(
      new CallbackMockResource(pp_instance()));
  PP_Resource resource_id = resource->SetupForTest();

  // Unref it, spin the message loop to run posted calls, and check that things
  // are in the expected states.
  resource_tracker->ReleaseResource(resource_id);
  {
    ProxyAutoUnlock unlock;
    base::MessageLoop::current()->RunUntilIdle();
  }
  resource->CheckFinalState();

  // "Resurrect" it and check that the callbacks are still dead.
  PP_Resource new_resource_id = resource->GetReference();
  {
    ProxyAutoUnlock unlock;
    base::MessageLoop::current()->RunUntilIdle();
  }
  resource->CheckFinalState();

  // Unref it again and do the same.
  resource_tracker->ReleaseResource(new_resource_id);
  {
    ProxyAutoUnlock unlock;
    base::MessageLoop::current()->RunUntilIdle();
  }
  resource->CheckFinalState();

  // This shouldn't be needed, but make sure there are no stranded tasks.
  {
    ProxyAutoUnlock unlock;
    base::MessageLoop::current()->RunUntilIdle();
  }
}

}  // namespace ppapi
