/**
 *
 * Agora Real Time Engagement
 * Created by Wei Hu in 2022-04.
 * Copyright (c) 2022 Agora IO. All rights reserved.
 *
 */
#include "rte_runtime/binding/nodejs/src/common/semaphore.h"

#include <assert.h>

#include "lib/signature.h"

bool rte_nodejs_sem_check_integrity(rte_nodejs_sem_t* self) {
  assert(self);

  if (rte_signature_get(&self->signature) != RTE_NODEJS_SEM_SIGNATURE) {
    return false;
  }
  return true;
}

void rte_nodejs_sem_init(rte_nodejs_sem_t* self) {
  assert(self);

  rte_signature_set(&self->signature, RTE_NODEJS_SEM_SIGNATURE);

  uv_mutex_init(&self->finished_lock);
  uv_cond_init(&self->finished_cond);
  self->finished = false;
}

void rte_nodejs_sem_signal(rte_nodejs_sem_t* self) {
  assert(self && rte_nodejs_sem_check_integrity(self));

  self->finished = true;
  uv_mutex_lock(&self->finished_lock);
  uv_cond_signal(&self->finished_cond);
  uv_mutex_unlock(&self->finished_lock);
}

void rte_nodejs_sem_wait(rte_nodejs_sem_t* self) {
  assert(self && rte_nodejs_sem_check_integrity(self));

  uv_mutex_lock(&self->finished_lock);
  while (!self->finished) {
    uv_cond_wait(&self->finished_cond, &self->finished_lock);
  }
  uv_mutex_unlock(&self->finished_lock);
}

void rte_nodejs_sem_cleanup(rte_nodejs_sem_t* self) {
  assert(self && rte_nodejs_sem_check_integrity(self));

  uv_mutex_destroy(&self->finished_lock);
  uv_cond_destroy(&self->finished_cond);
}
