/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
** Test socket IO timeouts
**
**
**
**
** Modification History:
** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
**           The debug mode will print all of the printfs associated with this test.
**           The regress mode will be the default mode. Since the regress tool limits
**           the output to a one line status:PASS or FAIL,all of the printf statements
**           have been handled with an if (debug_mode) statement.
***********************************************************************/
/***********************************************************************
** Includes
***********************************************************************/
/* Used to get the command line option */
#include "plgetopt.h"

#include <stdio.h>
#include "nspr.h"

#define NUM_THREADS 1
#define BASE_PORT   8000
#define DEFAULT_ACCEPT_TIMEOUT 2

typedef struct threadInfo {
    PRInt16 id;
    PRInt16 accept_timeout;
    PRLock *dead_lock;
    PRCondVar *dead_cv;
    PRInt32   *alive;
} threadInfo;

PRIntn failed_already = 0;
PRIntn debug_mode = 0;

#define LOCAL_SCOPE_STRING          "LOCAL scope"
#define GLOBAL_SCOPE_STRING         "GLOBAL scope"
#define GLOBAL_BOUND_SCOPE_STRING   "GLOBAL_BOUND scope"

void
thread_main(void *_info)
{
    threadInfo *info = (threadInfo *)_info;
    PRNetAddr listenAddr;
    PRNetAddr clientAddr;
    PRFileDesc *listenSock = NULL;
    PRFileDesc *clientSock;
    PRStatus rv;
    PRThreadScope tscope;
    char *scope_str;


    if (debug_mode) {
        printf("thread %d is alive\n", info->id);
    }
    tscope = PR_GetThreadScope(PR_GetCurrentThread());

    switch(tscope) {
        case PR_LOCAL_THREAD:
            scope_str = LOCAL_SCOPE_STRING;
            break;
        case PR_GLOBAL_THREAD:
            scope_str = GLOBAL_SCOPE_STRING;
            break;
        case PR_GLOBAL_BOUND_THREAD:
            scope_str = GLOBAL_BOUND_SCOPE_STRING;
            break;
        default:
            PR_NOT_REACHED("Invalid thread scope");
            break;
    }
    printf("thread id %d, scope %s\n", info->id, scope_str);

    listenSock = PR_NewTCPSocket();
    if (!listenSock) {
        if (debug_mode) {
            printf("unable to create listen socket\n");
        }
        failed_already=1;
        goto dead;
    }

    listenAddr.inet.family = PR_AF_INET;
    listenAddr.inet.port = PR_htons(BASE_PORT + info->id);
    listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
    rv = PR_Bind(listenSock, &listenAddr);
    if (rv == PR_FAILURE) {
        if (debug_mode) {
            printf("unable to bind\n");
        }
        failed_already=1;
        goto dead;
    }

    rv = PR_Listen(listenSock, 4);
    if (rv == PR_FAILURE) {
        if (debug_mode) {
            printf("unable to listen\n");
        }
        failed_already=1;
        goto dead;
    }

    if (debug_mode)
        printf("thread %d going into accept for %d seconds\n",
               info->id, info->accept_timeout + info->id);

    clientSock = PR_Accept(listenSock, &clientAddr, PR_SecondsToInterval(info->accept_timeout +info->id));

    if (clientSock == NULL) {
        if (PR_GetError() == PR_IO_TIMEOUT_ERROR) {
            if (debug_mode) {
                printf("PR_Accept() timeout worked!\n");
                printf("TEST PASSED! PR_Accept() returned error %d\n",
                       PR_IO_TIMEOUT_ERROR);
            }
        } else {
            if (debug_mode)
                printf("TEST FAILED! PR_Accept() returned error %d\n",
                       PR_GetError());
            failed_already=1;
        }
    } else {
        if (debug_mode) {
            printf ("TEST FAILED! PR_Accept() succeeded?\n");
        }
        failed_already=1;
        PR_Close(clientSock);
    }

dead:
    if (listenSock) {
        PR_Close(listenSock);
    }
    PR_Lock(info->dead_lock);
    (*info->alive)--;
    PR_NotifyCondVar(info->dead_cv);
    PR_Unlock(info->dead_lock);

    if (debug_mode) {
        printf("thread %d is dead\n", info->id);
    }

    PR_Free(info);
}

void
thread_test(PRThreadScope scope, PRInt32 num_threads)
{
    PRInt32 index;
    PRThread *thr;
    PRLock *dead_lock;
    PRCondVar *dead_cv;
    PRInt32 alive;

    if (debug_mode) {
        printf("IO Timeout test started with %d threads\n", num_threads);
    }

    dead_lock = PR_NewLock();
    dead_cv = PR_NewCondVar(dead_lock);
    alive = num_threads;

    for (index = 0; index < num_threads; index++) {
        threadInfo *info = (threadInfo *)PR_Malloc(sizeof(threadInfo));

        info->id = index;
        info->dead_lock = dead_lock;
        info->dead_cv = dead_cv;
        info->alive = &alive;
        info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT;

        thr = PR_CreateThread( PR_USER_THREAD,
                               thread_main,
                               (void *)info,
                               PR_PRIORITY_NORMAL,
                               scope,
                               PR_UNJOINABLE_THREAD,
                               0);

        if (!thr) {
            printf("Failed to create thread, error = %d(%d)\n",
                   PR_GetError(), PR_GetOSError());
            failed_already=1;

            PR_Lock(dead_lock);
            alive--;
            PR_Unlock(dead_lock);
        }
    }

    PR_Lock(dead_lock);
    while(alive) {
        if (debug_mode) {
            printf("main loop awake; alive = %d\n", alive);
        }
        PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT);
    }
    PR_Unlock(dead_lock);

    PR_DestroyCondVar(dead_cv);
    PR_DestroyLock(dead_lock);
}

int main(int argc, char **argv)
{
    PRInt32 num_threads = 0;

    /* The command line argument: -d is used to determine if the test is being run
    in debug mode. The regress tool requires only one line output:PASS or FAIL.
    All of the printfs associated with this test has been handled with a if (debug_mode)
    test.
    Usage: test_name [-d] [-t <threads>]
    */
    PLOptStatus os;
    PLOptState *opt = PL_CreateOptState(argc, argv, "dt:");
    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
        if (PL_OPT_BAD == os) {
            continue;
        }
        switch (opt->option)
        {
            case 'd':  /* debug mode */
                debug_mode = 1;
                break;
            case 't':  /* threads to involve */
                num_threads = atoi(opt->value);
                break;
            default:
                break;
        }
    }
    PL_DestroyOptState(opt);

    /* main test */

    if (0 == num_threads) {
        num_threads = NUM_THREADS;
    }

    PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0);
    PR_STDIO_INIT();

    printf("test with global bound thread\n");
    thread_test(PR_GLOBAL_BOUND_THREAD, num_threads);

    printf("test with local thread\n");
    thread_test(PR_LOCAL_THREAD, num_threads);

    printf("test with global thread\n");
    thread_test(PR_GLOBAL_THREAD, num_threads);

    PR_Cleanup();

    if (failed_already) {
        return 1;
    }
    else {
        return 0;
    }
}
