// 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 "cobalt/media/base/bind_to_current_loop.h"

#include <memory>
#include <utility>

#include "base/memory/free_deleter.h"
#include "base/message_loop.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "starboard/memory.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace media {

void BoundBoolSet(bool* var, bool val) { *var = val; }

void BoundBoolSetFromScopedPtr(bool* var, std::unique_ptr<bool> val) {
  *var = *val;
}

void BoundBoolSetFromScopedPtrFreeDeleter(
    bool* var, std::unique_ptr<bool, base::FreeDeleter> val) {
  *var = *val;
}

void BoundBoolSetFromScopedArray(bool* var, std::unique_ptr<bool[]> val) {
  *var = val[0];
}

void BoundBoolSetFromConstRef(bool* var, const bool& val) { *var = val; }

void BoundIntegersSet(int* a_var, int* b_var, int a_val, int b_val) {
  *a_var = a_val;
  *b_var = b_val;
}

// Various tests that check that the bound function is only actually executed
// on the message loop, not during the original Run.
class BindToCurrentLoopTest : public ::testing::Test {
 protected:
  base::MessageLoop loop_;
};

TEST_F(BindToCurrentLoopTest, Closure) {
  // Test the closure is run inside the loop, not outside it.
  base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                             base::WaitableEvent::InitialState::NOT_SIGNALED);
  base::Closure cb = BindToCurrentLoop(
      base::Bind(&base::WaitableEvent::Signal, base::Unretained(&waiter)));
  cb.Run();
  EXPECT_FALSE(waiter.IsSignaled());
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(waiter.IsSignaled());
}

TEST_F(BindToCurrentLoopTest, Bool) {
  bool bool_var = false;
  base::Callback<void(bool)> cb =
      BindToCurrentLoop(base::Bind(&BoundBoolSet, &bool_var));
  cb.Run(true);
  EXPECT_FALSE(bool_var);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(bool_var);
}

TEST_F(BindToCurrentLoopTest, BoundScopedPtrBool) {
  bool bool_val = false;
  std::unique_ptr<bool> scoped_ptr_bool(new bool(true));
  base::Closure cb = BindToCurrentLoop(base::Bind(
      &BoundBoolSetFromScopedPtr, &bool_val, base::Passed(&scoped_ptr_bool)));
  cb.Run();
  EXPECT_FALSE(bool_val);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(bool_val);
}

TEST_F(BindToCurrentLoopTest, PassedScopedPtrBool) {
  bool bool_val = false;
  std::unique_ptr<bool> scoped_ptr_bool(new bool(true));
  base::Callback<void(std::unique_ptr<bool>)> cb =
      BindToCurrentLoop(base::Bind(&BoundBoolSetFromScopedPtr, &bool_val));
  cb.Run(std::move(scoped_ptr_bool));
  EXPECT_FALSE(bool_val);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(bool_val);
}

TEST_F(BindToCurrentLoopTest, BoundScopedArrayBool) {
  bool bool_val = false;
  std::unique_ptr<bool[]> scoped_array_bool(new bool[1]);
  scoped_array_bool[0] = true;
  base::Closure cb =
      BindToCurrentLoop(base::Bind(&BoundBoolSetFromScopedArray, &bool_val,
                                   base::Passed(&scoped_array_bool)));
  cb.Run();
  EXPECT_FALSE(bool_val);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(bool_val);
}

TEST_F(BindToCurrentLoopTest, PassedScopedArrayBool) {
  bool bool_val = false;
  std::unique_ptr<bool[]> scoped_array_bool(new bool[1]);
  scoped_array_bool[0] = true;
  base::Callback<void(std::unique_ptr<bool[]>)> cb =
      BindToCurrentLoop(base::Bind(&BoundBoolSetFromScopedArray, &bool_val));
  cb.Run(std::move(scoped_array_bool));
  EXPECT_FALSE(bool_val);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(bool_val);
}

TEST_F(BindToCurrentLoopTest, BoundScopedPtrFreeDeleterBool) {
  bool bool_val = false;
  std::unique_ptr<bool, base::FreeDeleter> scoped_ptr_free_deleter_bool(
      static_cast<bool*>(SbMemoryAllocate(sizeof(bool))));
  *scoped_ptr_free_deleter_bool = true;
  base::Closure cb = BindToCurrentLoop(
      base::Bind(&BoundBoolSetFromScopedPtrFreeDeleter, &bool_val,
                 base::Passed(&scoped_ptr_free_deleter_bool)));
  cb.Run();
  EXPECT_FALSE(bool_val);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(bool_val);
}

TEST_F(BindToCurrentLoopTest, PassedScopedPtrFreeDeleterBool) {
  bool bool_val = false;
  std::unique_ptr<bool, base::FreeDeleter> scoped_ptr_free_deleter_bool(
      static_cast<bool*>(SbMemoryAllocate(sizeof(bool))));
  *scoped_ptr_free_deleter_bool = true;
  base::Callback<void(std::unique_ptr<bool, base::FreeDeleter>)> cb =
      BindToCurrentLoop(
          base::Bind(&BoundBoolSetFromScopedPtrFreeDeleter, &bool_val));
  cb.Run(std::move(scoped_ptr_free_deleter_bool));
  EXPECT_FALSE(bool_val);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(bool_val);
}

TEST_F(BindToCurrentLoopTest, BoolConstRef) {
  bool bool_var = false;
  bool true_var = true;
  const bool& true_ref = true_var;
  base::Closure cb = BindToCurrentLoop(
      base::Bind(&BoundBoolSetFromConstRef, &bool_var, true_ref));
  cb.Run();
  EXPECT_FALSE(bool_var);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(bool_var);
}

TEST_F(BindToCurrentLoopTest, Integers) {
  int a = 0;
  int b = 0;
  base::Callback<void(int, int)> cb =
      BindToCurrentLoop(base::Bind(&BoundIntegersSet, &a, &b));
  cb.Run(1, -1);
  EXPECT_EQ(a, 0);
  EXPECT_EQ(b, 0);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(a, 1);
  EXPECT_EQ(b, -1);
}

}  // namespace media
}  // namespace cobalt
