/* Copyright (c) 2015, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include "internal.h"

#include <openssl/crypto.h>

#include <stdio.h>


#if !defined(OPENSSL_NO_THREADS)

#if defined(OPENSSL_WINDOWS)

OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <windows.h>
OPENSSL_MSVC_PRAGMA(warning(pop))

typedef HANDLE thread_t;

static DWORD WINAPI thread_run(LPVOID arg) {
  void (*thread_func)(void);
  /* VC really doesn't like casting between data and function pointers. */
  OPENSSL_memcpy(&thread_func, &arg, sizeof(thread_func));
  thread_func();
  return 0;
}

static int run_thread(thread_t *out_thread, void (*thread_func)(void)) {
  void *arg;
  /* VC really doesn't like casting between data and function pointers. */
  OPENSSL_memcpy(&arg, &thread_func, sizeof(arg));

  *out_thread = CreateThread(NULL /* security attributes */,
                             0 /* default stack size */, thread_run, arg,
                             0 /* run immediately */, NULL /* ignore id */);
  return *out_thread != NULL;
}

static int wait_for_thread(thread_t thread) {
  return WaitForSingleObject(thread, INFINITE) == 0;
}

#else

#include <pthread.h>
#include <string.h>
#include <time.h>

typedef pthread_t thread_t;

static void *thread_run(void *arg) {
  void (*thread_func)(void) = arg;
  thread_func();
  return NULL;
}

static int run_thread(thread_t *out_thread, void (*thread_func)(void)) {
  return pthread_create(out_thread, NULL /* default attributes */, thread_run,
                        thread_func) == 0;
}

static int wait_for_thread(thread_t thread) {
  return pthread_join(thread, NULL) == 0;
}

#endif  /* OPENSSL_WINDOWS */

static unsigned g_once_init_called = 0;

static void once_init(void) {
  g_once_init_called++;

  /* Sleep briefly so one |call_once_thread| instance will call |CRYPTO_once|
   * while the other is running this function. */
#if defined(OPENSSL_WINDOWS)
  Sleep(1 /* milliseconds */);
#else
  struct timespec req;
  OPENSSL_memset(&req, 0, sizeof(req));
  req.tv_nsec = 1000000;
  nanosleep(&req, NULL);
#endif
}

static CRYPTO_once_t g_test_once = CRYPTO_ONCE_INIT;

static void call_once_thread(void) {
  CRYPTO_once(&g_test_once, once_init);
}

static CRYPTO_once_t once_init_value = CRYPTO_ONCE_INIT;
static CRYPTO_once_t once_bss;

static struct CRYPTO_STATIC_MUTEX mutex_init_value = CRYPTO_STATIC_MUTEX_INIT;
static struct CRYPTO_STATIC_MUTEX mutex_bss;

static CRYPTO_EX_DATA_CLASS ex_data_class_value = CRYPTO_EX_DATA_CLASS_INIT;
static CRYPTO_EX_DATA_CLASS ex_data_class_bss;

static int test_once(void) {
  if (g_once_init_called != 0) {
    fprintf(stderr, "g_once_init_called was non-zero at start.\n");
    return 0;
  }

  thread_t thread1, thread2;
  if (!run_thread(&thread1, call_once_thread) ||
      !run_thread(&thread2, call_once_thread) ||
      !wait_for_thread(thread1) ||
      !wait_for_thread(thread2)) {
    fprintf(stderr, "thread failed.\n");
    return 0;
  }

  CRYPTO_once(&g_test_once, once_init);

  if (g_once_init_called != 1) {
    fprintf(stderr, "Expected init function to be called once, but found %u.\n",
            g_once_init_called);
    return 0;
  }

  if (FIPS_mode()) {
    /* Our FIPS tooling currently requires that |CRYPTO_ONCE_INIT|,
     * |CRYPTO_STATIC_MUTEX_INIT| and |CRYPTO_EX_DATA_CLASS| are all zeros and
     * so can be placed in the BSS section. */
    if (OPENSSL_memcmp((void *)&once_init_value, (void *)&once_bss,
                       sizeof(CRYPTO_once_t)) != 0) {
      fprintf(stderr, "CRYPTO_ONCE_INIT did not expand to all zeros.\n");
      return 0;
    }

    if (OPENSSL_memcmp((void *)&mutex_init_value, (void *)&mutex_bss,
                       sizeof(struct CRYPTO_STATIC_MUTEX)) != 0) {
      fprintf(stderr, "CRYPTO_STATIC_MUTEX did not expand to all zeros.\n");
      return 0;
    }

    if (OPENSSL_memcmp((void *)&ex_data_class_value, (void *)&ex_data_class_bss,
                       sizeof(CRYPTO_EX_DATA_CLASS))) {
      fprintf(stderr,
              "CRYPTO_EX_DATA_CLASS_INIT did not expand to all zeros.\n");
      return 0;
    }
  }

  return 1;
}


static int g_test_thread_ok = 0;
static unsigned g_destructor_called_count = 0;

static void thread_local_destructor(void *arg) {
  if (arg == NULL) {
    return;
  }

  unsigned *count = arg;
  (*count)++;
}

static void thread_local_test_thread(void) {
  void *ptr = CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_TEST);
  if (ptr != NULL) {
    return;
  }

  if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_TEST,
                               &g_destructor_called_count,
                               thread_local_destructor)) {
    return;
  }

  if (CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_TEST) !=
      &g_destructor_called_count) {
    return;
  }

  g_test_thread_ok = 1;
}

static void thread_local_test2_thread(void) {}

static int test_thread_local(void) {
  void *ptr = CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_TEST);
  if (ptr != NULL) {
    fprintf(stderr, "Thread-local data was non-NULL at start.\n");
  }

  thread_t thread;
  if (!run_thread(&thread, thread_local_test_thread) ||
      !wait_for_thread(thread)) {
    fprintf(stderr, "thread failed.\n");
    return 0;
  }

  if (!g_test_thread_ok) {
    fprintf(stderr, "Thread-local data didn't work in thread.\n");
    return 0;
  }

  if (g_destructor_called_count != 1) {
    fprintf(stderr,
            "Destructor should have been called once, but actually called %u "
            "times.\n",
            g_destructor_called_count);
    return 0;
  }

  /* thread_local_test2_thread doesn't do anything, but it tests that the
   * thread destructor function works even if thread-local storage wasn't used
   * for a thread. */
  if (!run_thread(&thread, thread_local_test2_thread) ||
      !wait_for_thread(thread)) {
    fprintf(stderr, "thread failed.\n");
    return 0;
  }

  return 1;
}

int main(int argc, char **argv) {
  if (!test_once() ||
      !test_thread_local()) {
    return 1;
  }

  printf("PASS\n");
  return 0;
}

#else  /* OPENSSL_NO_THREADS */

int main(int argc, char **argv) {
  printf("PASS\n");
  return 0;
}

#endif
