// Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "include/dart_api.h"
#include "vm/bootstrap_natives.h"
#include "vm/os_thread.h"

namespace dart {

static void DeleteMutex(void* isolate_data, void* mutex_pointer) {
  delete reinterpret_cast<Mutex*>(mutex_pointer);
}

static constexpr int kMutexNativeField = 0;

DEFINE_FFI_NATIVE_ENTRY(Mutex_Initialize, void, (Dart_Handle mutex_handle)) {
  Mutex* mutex = new Mutex();
  Dart_Handle err = Dart_SetNativeInstanceField(
      mutex_handle, kMutexNativeField, reinterpret_cast<intptr_t>(mutex));
  if (Dart_IsError(err)) {
    delete mutex;
    Dart_PropagateError(err);
  }
  Dart_NewFinalizableHandle(mutex_handle, mutex, sizeof(Mutex), DeleteMutex);
};

DEFINE_FFI_NATIVE_ENTRY(Mutex_RunLocked,
                        Dart_Handle,
                        (Dart_Handle mutex_handle,
                         Dart_Handle closure_handle)) {
  Mutex* mutex;
  Dart_Handle result = Dart_GetNativeInstanceField(
      mutex_handle, kMutexNativeField, reinterpret_cast<intptr_t*>(&mutex));
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  mutex->Lock();
  result = Dart_InvokeClosure(closure_handle, 0, nullptr);
  mutex->Unlock();
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  return result;
}

static void DeleteConditionVariable(void* isolate_data, void* condvar_pointer) {
  delete reinterpret_cast<ConditionVariable*>(condvar_pointer);
}

static constexpr int kCondVarNativeField = 0;

DEFINE_FFI_NATIVE_ENTRY(ConditionVariable_Initialize,
                        void,
                        (Dart_Handle condvar_handle)) {
  ConditionVariable* condvar = new ConditionVariable();
  Dart_Handle err = Dart_SetNativeInstanceField(
      condvar_handle, kCondVarNativeField, reinterpret_cast<intptr_t>(condvar));
  if (Dart_IsError(err)) {
    delete condvar;
    Dart_PropagateError(err);
  }
  Dart_NewFinalizableHandle(condvar_handle, condvar, sizeof(ConditionVariable),
                            DeleteConditionVariable);
}

DEFINE_FFI_NATIVE_ENTRY(ConditionVariable_Wait,
                        void,
                        (Dart_Handle condvar_handle,
                         Dart_Handle mutex_handle)) {
  Mutex* mutex;
  Dart_Handle result_mutex = Dart_GetNativeInstanceField(
      mutex_handle, kCondVarNativeField, reinterpret_cast<intptr_t*>(&mutex));
  if (Dart_IsError(result_mutex)) {
    Dart_PropagateError(result_mutex);
  }
  ConditionVariable* condvar;
  Dart_Handle result_condvar =
      Dart_GetNativeInstanceField(condvar_handle, kCondVarNativeField,
                                  reinterpret_cast<intptr_t*>(&condvar));
  if (Dart_IsError(result_condvar)) {
    Dart_PropagateError(result_condvar);
  }
  condvar->Wait(mutex);
}

DEFINE_FFI_NATIVE_ENTRY(ConditionVariable_Notify,
                        void,
                        (Dart_Handle condvar_handle)) {
  ConditionVariable* condvar;
  Dart_Handle result_condvar =
      Dart_GetNativeInstanceField(condvar_handle, kCondVarNativeField,
                                  reinterpret_cast<intptr_t*>(&condvar));
  if (Dart_IsError(result_condvar)) {
    Dart_PropagateError(result_condvar);
  }
  condvar->Notify();
}

DEFINE_FFI_NATIVE_ENTRY(ConditionVariable_NotifyAll,
                        void,
                        (Dart_Handle condvar_handle)) {
  ConditionVariable* condvar;
  Dart_Handle result_condvar =
      Dart_GetNativeInstanceField(condvar_handle, kCondVarNativeField,
                                  reinterpret_cast<intptr_t*>(&condvar));
  if (Dart_IsError(result_condvar)) {
    Dart_PropagateError(result_condvar);
  }
  condvar->NotifyAll();
}

}  // namespace dart
