/* ====================================================================
 * Copyright (c) 2016 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 */

#include <stdio.h>

#include <openssl/crypto.h>
#include "internal/threads.h"

#if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG)

typedef unsigned int thread_t;

static int run_thread(thread_t *t, void (*f)(void))
{
    f();
    return 1;
}

static int wait_for_thread(thread_t thread)
{
    return 1;
}

#elif defined(OPENSSL_SYS_WINDOWS)

typedef HANDLE thread_t;

static DWORD WINAPI thread_run(LPVOID arg)
{
    void (*f)(void);

    *(void **) (&f) = arg;

    f();
    return 0;
}

static int run_thread(thread_t *t, void (*f)(void))
{
    *t = CreateThread(NULL, 0, thread_run, *(void **) &f, 0, NULL);
    return *t != NULL;
}

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

#else

typedef pthread_t thread_t;

static void *thread_run(void *arg)
{
    void (*f)(void);

    *(void **) (&f) = arg;

    f();
    return NULL;
}

static int run_thread(thread_t *t, void (*f)(void))
{
    return pthread_create(t, NULL, thread_run, *(void **) &f) == 0;
}

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

#endif

static int test_lock(void)
{
    CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();

    if (!CRYPTO_THREAD_read_lock(lock)) {
        fprintf(stderr, "CRYPTO_THREAD_read_lock() failed\n");
        return 0;
    }

    if (!CRYPTO_THREAD_unlock(lock)) {
        fprintf(stderr, "CRYPTO_THREAD_unlock() failed\n");
        return 0;
    }

    CRYPTO_THREAD_lock_free(lock);

    return 1;
}

static CRYPTO_ONCE once_run = CRYPTO_ONCE_STATIC_INIT;
static unsigned once_run_count = 0;

static void once_do_run(void)
{
    once_run_count++;
}

static void once_run_thread_cb(void)
{
    CRYPTO_THREAD_run_once(&once_run, once_do_run);
}

static int test_once(void)
{
    thread_t thread;
    if (!run_thread(&thread, once_run_thread_cb) ||
        !wait_for_thread(thread))
    {
        fprintf(stderr, "run_thread() failed\n");
        return 0;
    }

    if (!CRYPTO_THREAD_run_once(&once_run, once_do_run)) {
        fprintf(stderr, "CRYPTO_THREAD_run_once() failed\n");
        return 0;
    }

    if (once_run_count != 1) {
        fprintf(stderr, "once run %u times\n", once_run_count);
        return 0;
    }

    return 1;
}

static CRYPTO_THREAD_LOCAL thread_local_key;
static unsigned destructor_run_count = 0;
static int thread_local_thread_cb_ok = 0;

static void thread_local_destructor(void *arg)
{
    unsigned *count;

    if (arg == NULL)
        return;

    count = arg;

    (*count)++;
}

static void thread_local_thread_cb(void)
{
    void *ptr;

    ptr = CRYPTO_THREAD_get_local(&thread_local_key);
    if (ptr != NULL) {
        fprintf(stderr, "ptr not NULL\n");
        return;
    }

    if (!CRYPTO_THREAD_set_local(&thread_local_key, &destructor_run_count)) {
        fprintf(stderr, "CRYPTO_THREAD_set_local() failed\n");
        return;
    }

    ptr = CRYPTO_THREAD_get_local(&thread_local_key);
    if (ptr != &destructor_run_count) {
        fprintf(stderr, "invalid ptr\n");
        return;
    }

    thread_local_thread_cb_ok = 1;
}

static int test_thread_local(void)
{
    thread_t thread;
    void *ptr = NULL;

    if (!CRYPTO_THREAD_init_local(&thread_local_key, thread_local_destructor)) {
        fprintf(stderr, "CRYPTO_THREAD_init_local() failed\n");
        return 0;
    }

    ptr = CRYPTO_THREAD_get_local(&thread_local_key);
    if (ptr != NULL) {
        fprintf(stderr, "ptr not NULL\n");
        return 0;
    }

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

    if (thread_local_thread_cb_ok != 1) {
        fprintf(stderr, "thread-local thread callback failed\n");
        return 0;
    }

#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)

    ptr = CRYPTO_THREAD_get_local(&thread_local_key);
    if (ptr != NULL) {
        fprintf(stderr, "ptr not NULL\n");
        return 0;
    }

# if !defined(OPENSSL_SYS_WINDOWS)
    if (destructor_run_count != 1) {
        fprintf(stderr, "thread-local destructor run %u times\n",
                destructor_run_count);
        return 0;
    }
# endif

#endif

    if (!CRYPTO_THREAD_cleanup_local(&thread_local_key)) {
        fprintf(stderr, "CRYPTO_THREAD_cleanup_local() failed\n");
        return 0;
    }

    return 1;
}

int main(int argc, char **argv)
{
    if (!test_lock())
      return 1;

    if (!test_once())
      return 1;

    if (!test_thread_local())
      return 1;

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