// Copyright 2013 The Flutter 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 "tonic/dart_microtask_queue.h"

#include "tonic/common/build_config.h"
#include "tonic/dart_state.h"
#include "tonic/logging/dart_invoke.h"

#ifdef OS_IOS
#include <pthread.h>
#endif

namespace tonic {
namespace {

#ifdef OS_IOS
// iOS doesn't support the thread_local keyword.

pthread_key_t g_queue_key;
pthread_once_t g_queue_key_once = PTHREAD_ONCE_INIT;

void MakeKey() {
  pthread_key_create(&g_queue_key, nullptr);
}

void SetQueue(DartMicrotaskQueue* queue) {
  pthread_once(&g_queue_key_once, MakeKey);
  pthread_setspecific(g_queue_key, queue);
}

DartMicrotaskQueue* GetQueue() {
  return static_cast<tonic::DartMicrotaskQueue*>(
      pthread_getspecific(g_queue_key));
}

#else

thread_local DartMicrotaskQueue* g_queue = nullptr;

void SetQueue(DartMicrotaskQueue* queue) {
  g_queue = queue;
}

DartMicrotaskQueue* GetQueue() {
  return g_queue;
}

#endif

}  // namespace

DartMicrotaskQueue::DartMicrotaskQueue() : last_error_(kNoError) {}

DartMicrotaskQueue::~DartMicrotaskQueue() = default;

void DartMicrotaskQueue::StartForCurrentThread() {
  SetQueue(new DartMicrotaskQueue());
}

DartMicrotaskQueue* DartMicrotaskQueue::GetForCurrentThread() {
  return GetQueue();
}

void DartMicrotaskQueue::ScheduleMicrotask(Dart_Handle callback) {
  queue_.emplace_back(DartState::Current(), callback);
}

void DartMicrotaskQueue::RunMicrotasks() {
  while (!queue_.empty()) {
    MicrotaskQueue local;
    std::swap(queue_, local);
    for (const auto& callback : local) {
      if (auto dart_state = callback.dart_state().lock()) {
        DartState::Scope dart_scope(dart_state.get());
        Dart_Handle result = Dart_InvokeClosure(callback.value(), 0, nullptr);
        // If the Dart program has set a return code, then it is intending to
        // shut down by way of a fatal error, and so there is no need to emit a
        // log message.
        if (!dart_state->has_set_return_code() || !Dart_IsError(result) ||
            !Dart_IsFatalError(result)) {
          LogIfError(result);
        }
        DartErrorHandleType error = GetErrorHandleType(result);
        if (error != kNoError) {
          last_error_ = error;
        }
        dart_state->MessageEpilogue(result);
        if (!Dart_CurrentIsolate())
          return;
      }
    }
  }
}

void DartMicrotaskQueue::Destroy() {
  TONIC_DCHECK(this == GetForCurrentThread());
  SetQueue(nullptr);
  delete this;
}

DartErrorHandleType DartMicrotaskQueue::GetLastError() {
  return last_error_;
}

}  // namespace tonic
