/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

#include "prologue.h"

#include <string.h>
#include <errno.h>

#include "log.h"
#include "strfmt.h"
#include "thread.h"
#include "async_signal.h"
#include "async_event.h"
#include "async_wait.h"

#undef HAVE_THREAD_NAMES

#ifdef GOT_PTHREADS
typedef struct {
  ThreadFunction *function;
  void *argument;
  char name[];
} RunThreadArgument;

static void *
runThread (void *argument) {
  RunThreadArgument *run = argument;

  setThreadName(run->name);
  logMessage(LOG_CATEGORY(ASYNC_EVENTS), "thread starting: %s", run->name);
  void *result = run->function(run->argument);
  logMessage(LOG_CATEGORY(ASYNC_EVENTS), "thread finished: %s", run->name);

  free(run);
  return result;
}

typedef struct {
  const char *const name;
  pthread_t *const thread;
  const pthread_attr_t *const attributes;
  ThreadFunction *const function;
  void *const argument;

  int error;
} CreateThreadParameters;

static int
createActualThread (void *parameters) {
  CreateThreadParameters *create = parameters;
  RunThreadArgument *run;

  if ((run = malloc(sizeof(*run) + strlen(create->name) + 1))) {
    memset(run, 0, sizeof(*run));
    run->function = create->function;
    run->argument = create->argument;
    strcpy(run->name, create->name);

    logMessage(LOG_CATEGORY(ASYNC_EVENTS), "creating thread: %s", create->name);
    create->error = pthread_create(create->thread, create->attributes, runThread, run);
    if (!create->error) return 1;
    logMessage(LOG_CATEGORY(ASYNC_EVENTS), "thread not created: %s: %s", create->name, strerror(create->error));

    free(run);
  } else {
    create->error = errno;
    logMallocError();
  }

  return 0;
}

#ifdef ASYNC_CAN_BLOCK_SIGNALS
ASYNC_WITH_SIGNALS_BLOCKED_FUNCTION(createSignalSafeThread) {
  static const int signals[] = {
#ifdef SIGINT
    SIGINT,
#endif /* SIGINT */

#ifdef SIGTERM
    SIGTERM,
#endif /* SIGTERM */

#ifdef SIGCHLD
    SIGCHLD,
#endif /* SIGCHLD */

    0
  };

  CreateThreadParameters *create = data;
  const int *signal = signals;

  while (*signal) {
    asyncSetSignalBlocked(*signal, 1);
    signal += 1;
  }

  createActualThread(create);
}
#endif /* ASYNC_CAN_BLOCK_SIGNALS */

int
createThread (
  const char *name,
  pthread_t *thread, const pthread_attr_t *attributes,
  ThreadFunction *function, void *argument
) {
  CreateThreadParameters create = {
    .name = name,
    .thread = thread,
    .attributes = attributes,
    .function = function,
    .argument = argument
  };

#ifdef ASYNC_CAN_BLOCK_SIGNALS
  asyncWithObtainableSignalsBlocked(createSignalSafeThread, &create);
#else /* ASYNC_CAN_BLOCK_SIGNALS */
  createActualThread(&create);
#endif /* ASYNC_CAN_BLOCK_SIGNALS */

  return create.error;
}

typedef struct {
  ThreadFunction *const function;
  void *const argument;

  AsyncEvent *event;
  unsigned returned:1;
} CallThreadFunctionData;

THREAD_FUNCTION(runThreadFunction) {
  CallThreadFunctionData *ctf = argument;
  void *result = ctf->function? ctf->function(ctf->argument): NULL;

  asyncSignalEvent(ctf->event, NULL);
  return result;
}

ASYNC_EVENT_CALLBACK(handleThreadFunctionReturned) {
  CallThreadFunctionData *ctf = parameters->eventData;

  ctf->returned = 1;
}

ASYNC_CONDITION_TESTER(testThreadFunctionReturned) {
  CallThreadFunctionData *ctf = data;

  return ctf->returned;
}

int
callThreadFunction (
  const char *name, ThreadFunction *function,
  void *argument, void **result
) {
  int called = 0;

  CallThreadFunctionData ctf = {
    .function = function,
    .argument = argument,

    .returned = 0
  };

  if ((ctf.event = asyncNewEvent(handleThreadFunctionReturned, &ctf))) {
    pthread_t thread;
    int error = createThread(name, &thread, NULL, runThreadFunction, &ctf);

    if (!error) {
      asyncWaitFor(testThreadFunctionReturned, &ctf);

      {
        void *r;

        if (!result) result = &r;
        pthread_join(thread, result);
      }

      called = 1;
    } else {
      errno = error;
    }

    asyncDiscardEvent(ctf.event);
  }

  return called;
}

int
lockMutex (pthread_mutex_t *mutex) {
  int result = pthread_mutex_lock(mutex);

  logSymbol(LOG_CATEGORY(ASYNC_EVENTS), mutex, "mutex lock");
  return result;
}

int
unlockMutex (pthread_mutex_t *mutex) {
  logSymbol(LOG_CATEGORY(ASYNC_EVENTS), mutex, "mutex unlock");
  return pthread_mutex_unlock(mutex);
}

#if defined(HAVE_PTHREAD_GETNAME_NP) && defined(__GLIBC__)
#define HAVE_THREAD_NAMES

size_t
formatThreadName (char *buffer, size_t size) {
  int error = pthread_getname_np(pthread_self(), buffer, size);

  return error? 0: strlen(buffer);
}

void
setThreadName (const char *name) {
  pthread_setname_np(pthread_self(), name);
}

#elif defined(HAVE_PTHREAD_GETNAME_NP) && defined(__APPLE__)
#define HAVE_THREAD_NAMES

size_t
formatThreadName (char *buffer, size_t size) {
  {
    int error = pthread_getname_np(pthread_self(), buffer, size);

    if (error) return 0;
    if (*buffer) return strlen(buffer);
  }

  if (pthread_main_np()) {
    size_t length;

    STR_BEGIN(buffer, size);
    STR_PRINTF("main");
    length = STR_LENGTH;
    STR_END;

    return length;
  }

  return 0;
}

void
setThreadName (const char *name) {
  pthread_setname_np(name);
}

#endif /* thread names */
#endif /* GOT_PTHREADS */

#ifndef HAVE_THREAD_NAMES
size_t
formatThreadName (char *buffer, size_t size) {
  return 0;
}

void
setThreadName (const char *name) {
}
#endif /* HAVE_THREAD_NAMES */

#if defined(PTHREAD_MUTEX_INITIALIZER)
static void
createThreadSpecificDataKey (ThreadSpecificDataControl *ctl) {
  int error;

  pthread_mutex_lock(&ctl->mutex);
    if (!ctl->key.created) {
      error = pthread_key_create(&ctl->key.value, ctl->destroy);

      if (!error) {
        ctl->key.created = 1;
      } else {
        logActionError(error, "pthread_key_create");
      }
    }
  pthread_mutex_unlock(&ctl->mutex);
}

#ifdef ASYNC_CAN_BLOCK_SIGNALS
ASYNC_WITH_SIGNALS_BLOCKED_FUNCTION(createThreadSpecificDataKeyWithSignalsBlocked) {
  ThreadSpecificDataControl *ctl = data;

  createThreadSpecificDataKey(ctl);
}
#endif /* ASYNC_CAN_BLOCK_SIGNALS */

void *
getThreadSpecificData (ThreadSpecificDataControl *ctl) {
  int error;

#ifdef ASYNC_CAN_BLOCK_SIGNALS
  asyncWithAllSignalsBlocked(createThreadSpecificDataKeyWithSignalsBlocked, ctl);
#else /* ASYNC_CAN_BLOCK_SIGNALS */
  createThreadSpecificDataKey(ctl);
#endif /* ASYNC_CAN_BLOCK_SIGNALS */

  if (ctl->key.created) {
    void *tsd = pthread_getspecific(ctl->key.value);
    if (tsd) return tsd;

    if ((tsd = ctl->new())) {
      if (!(error = pthread_setspecific(ctl->key.value, tsd))) {
        return tsd;
      } else {
        logActionError(error, "pthread_setspecific");
      }

      ctl->destroy(tsd);
    }
  }

  return NULL;
}

#else /* thread specific data */
#include "program.h"

static void
exitThreadSpecificData (void *data) {
  ThreadSpecificDataControl *ctl = data;

  if (ctl->data) {
    ctl->destroy(ctl->data);
    ctl->data = NULL;
  }
}

void *
getThreadSpecificData (ThreadSpecificDataControl *ctl) {
  if (!ctl->data) {
    if ((ctl->data = ctl->new())) {
      onProgramExit("thread-specific-data", exitThreadSpecificData, ctl);
    }
  }

  return ctl->data;
}
#endif /* thread specific data */
