// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/thread.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

struct ThreadLocalValue {
  ThreadLocalValue() : destroyed(false) {}
  bool destroyed;
};

struct Context {
  Context() : key(), in_value(), out_value(), destroyed_before_exit(false) {}

  SbThreadLocalKey key;
  void* in_value;
  void* out_value;
  bool destroyed_before_exit;
};

void DestroyThreadLocalValue(void* value) {
  ThreadLocalValue* thread_local_value = static_cast<ThreadLocalValue*>(value);
  thread_local_value->destroyed = true;
}

void* EntryPoint(void* context) {
  Context* real_context = static_cast<Context*>(context);
  SbThreadSetLocalValue(real_context->key, real_context->in_value);
  real_context->out_value = SbThreadGetLocalValue(real_context->key);
  ThreadLocalValue* thread_local_value =
      static_cast<ThreadLocalValue*>(real_context->out_value);
  real_context->destroyed_before_exit = thread_local_value->destroyed;

  return NULL;
}

void DoSunnyDayTest(bool use_destructor) {
  const int kThreads = 16;
  ThreadLocalValue values[kThreads];
  Context contexts[kThreads];
  SbThread threads[kThreads];
  ThreadLocalValue my_value;

  SbThreadLocalKey key =
      SbThreadCreateLocalKey(use_destructor ? DestroyThreadLocalValue : NULL);
  EXPECT_TRUE(SbThreadIsValidLocalKey(key));
  SbThreadSetLocalValue(key, &my_value);
  for (int i = 0; i < kThreads; ++i) {
    contexts[i].key = key;
    contexts[i].in_value = &values[i];
  }

  for (int i = 0; i < kThreads; ++i) {
    threads[i] = SbThreadCreate(0, kSbThreadNoPriority, kSbThreadNoAffinity,
                                true, NULL, EntryPoint, &contexts[i]);
  }

  for (int i = 0; i < kThreads; ++i) {
    EXPECT_TRUE(SbThreadIsValid(threads[i]));
    EXPECT_TRUE(SbThreadJoin(threads[i], NULL));
    EXPECT_EQ(contexts[i].in_value, contexts[i].out_value);

    // The destructor for all thread-local values will be called at thread exit
    // time.
    EXPECT_FALSE(contexts[i].destroyed_before_exit);
    if (use_destructor) {
      EXPECT_TRUE(values[i].destroyed);
    } else {
      EXPECT_FALSE(values[i].destroyed);
    }
  }

  EXPECT_FALSE(my_value.destroyed);
  SbThreadDestroyLocalKey(key);

  // The destructor will never be called on my_value.
  EXPECT_FALSE(my_value.destroyed);
}

// Helper function that ensures that the returned key is not recycled.
SbThreadLocalKey CreateTLSKey_NoRecycle(SbThreadLocalDestructor dtor) {
  SbThreadLocalKey key = SbThreadCreateLocalKey(NULL);
  EXPECT_EQ(NULL, SbThreadGetLocalValue(key));
  // Some Starboard implementations may recycle the original key, so this test
  // ensures that in that case it will be reset to NULL.
  SbThreadSetLocalValue(key, reinterpret_cast<void*>(1));
  SbThreadDestroyLocalKey(key);
  key = SbThreadCreateLocalKey(DestroyThreadLocalValue);
  return key;
}

// Tests the expectation that thread at-exit destructors don't
// run for ThreadLocal pointers that are set to NULL.
TEST(SbThreadLocalValueTest, NoDestructorsForNullValue) {
  static int s_num_destructor_calls = 0;  // Must be initialized to 0.
  s_num_destructor_calls = 0;             // Allows test to be re-run.

  // Thread functionality needs to bind to functions. In C++11 we'd use a
  // lambda function to tie everything together locally, but this
  // function-scoped struct with static members emulates this functionality
  // pretty well.
  struct LocalStatic {
    // Used as a fake destructor for thread-local-storage objects in this
    // test.
    static void CountsDestructorCalls(void* /*value*/) {
      s_num_destructor_calls++;
    }

    // Sets a thread local non-NULL value, and then sets it back to NULL.
    static void* ThreadEntryPoint(void* ptr) {
      SbThreadLocalKey key = *static_cast<SbThreadLocalKey*>(ptr);
      EXPECT_EQ(NULL, SbThreadGetLocalValue(key));
      // Set the value and then NULL it out. We expect that because the final
      // value set was NULL, that the destructor attached to the thread's
      // at-exit function will not run.
      SbThreadSetLocalValue(key, reinterpret_cast<void*>(1));
      SbThreadSetLocalValue(key, NULL);
      return NULL;
    }
  };

  // Setup the thread key and bind the fake test destructor.
  SbThreadLocalKey key =
      CreateTLSKey_NoRecycle(LocalStatic::CountsDestructorCalls);
  EXPECT_EQ(NULL, SbThreadGetLocalValue(key));

  // Spawn the thread.
  SbThread thread = SbThreadCreate(
      0,                    // Signals automatic thread stack size.
      kSbThreadNoPriority,  // Signals default priority.
      kSbThreadNoAffinity,  // Signals default affinity.
      true,                 // joinable thread.
      "TestThread",
      LocalStatic::ThreadEntryPoint,
      static_cast<void*>(&key));

  ASSERT_NE(kSbThreadInvalid, thread) << "Thread creation not successful";
  // 2nd param is return value from ThreadEntryPoint, which is always NULL.
  ASSERT_TRUE(SbThreadJoin(thread, NULL));

  // No destructors should have run.
  EXPECT_EQ(0, s_num_destructor_calls);

  SbThreadDestroyLocalKey(key);
}

TEST(SbThreadLocalValueTest, SunnyDay) {
  DoSunnyDayTest(true);
}

TEST(SbThreadLocalValueTest, SunnyDayNoDestructor) {
  DoSunnyDayTest(false);
}

TEST(SbThreadLocalValueTest, SunnyDayFreshlyCreatedValuesAreNull) {
  SbThreadLocalKey key = CreateTLSKey_NoRecycle(NULL);  // NULL dtor.
  EXPECT_EQ(NULL, SbThreadGetLocalValue(key));

  EXPECT_EQ(NULL, SbThreadGetLocalValue(key));
  SbThreadDestroyLocalKey(key);
}

TEST(SbThreadLocalValueTest, SunnyDayMany) {
  const int kMany = (2 * SB_MAX_THREAD_LOCAL_KEYS) / 3;
  SbThreadLocalKey keys[kMany];

  for (int i = 0; i < kMany; ++i) {
    keys[i] = SbThreadCreateLocalKey(NULL);
    EXPECT_TRUE(SbThreadIsValidLocalKey(keys[i])) << "key #" << i;
  }

  for (int i = 0; i < kMany; ++i) {
    SbThreadDestroyLocalKey(keys[i]);
  }
}

}  // namespace
}  // namespace nplb
}  // namespace starboard
