#include "aos/complex_thread_local.h"

#include <pthread.h>

#include "aos/die.h"
#include "aos/once.h"

#define SIMPLE_CHECK(call)              \
  do {                                  \
    const int value = call;             \
    if (value != 0) {                   \
      PRDie(value, "%s failed", #call); \
    }                                   \
  } while (false)

namespace aos {
namespace {

void ExecuteDestructorList(void *v) {
  for (const ComplexThreadLocalDestructor *c =
           static_cast<ComplexThreadLocalDestructor *>(v);
       c != nullptr; c = c->next) {
    c->function(c->param);
  }
}

pthread_key_t *CreateKey() {
  static pthread_key_t r;
  SIMPLE_CHECK(pthread_key_create(&r, ExecuteDestructorList));
  return &r;
}

::aos::Once<pthread_key_t> key_once(CreateKey);

} // namespace

void ComplexThreadLocalDestructor::Add() {
  static_assert(
      ::std::is_pod<ComplexThreadLocalDestructor>::value,
      "ComplexThreadLocalDestructor might not be safe to pass through void*");
  pthread_key_t *const key = key_once.Get();

  next = static_cast<ComplexThreadLocalDestructor *>(pthread_getspecific(*key));
  SIMPLE_CHECK(pthread_setspecific(*key, this));
}

void ComplexThreadLocalDestructor::Remove() {
  pthread_key_t *const key = key_once.Get();

  ComplexThreadLocalDestructor *previous = nullptr;
  for (ComplexThreadLocalDestructor *c =
           static_cast<ComplexThreadLocalDestructor *>(
               pthread_getspecific(*key));
       c != nullptr; c = c->next) {
    if (c == this) {
      // If it's the first one.
      if (previous == nullptr) {
        SIMPLE_CHECK(pthread_setspecific(*key, next));
      } else {
        previous->next = next;
      }
      return;
    }
    previous = c;
  }
  ::aos::Die("%p is not in the destructor list\n", this);
}

}  // namespace aos
