/* -*- 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/. */

/***********************************************************************
**
** This server simulates a server running in loopback mode.
**
** The idea is that a single server is created.  The server initially creates
** a number of worker threads.  Then, with the server running, a number of
** clients are created which start requesting service from the server.
**
**
** Modification History:
** 19-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 "nspr.h"
#include "pprthred.h"

#include <string.h>

#define PORT 15004
#define THREAD_STACKSIZE 0

#define PASS 0
#define FAIL 1
static int debug_mode = 0;
static int failed_already = 0;

static int _iterations = 1000;
static int _clients = 1;
static int _client_data = 250;
static int _server_data = (8*1024);

static PRThreadScope ServerScope, ClientScope;

#define SERVER "Server"
#define MAIN   "Main"

#define SERVER_STATE_STARTUP 0
#define SERVER_STATE_READY   1
#define SERVER_STATE_DYING   2
#define SERVER_STATE_DEAD    4
int       ServerState;
PRLock    *ServerStateCVLock;
PRCondVar *ServerStateCV;

#undef DEBUGPRINTS
#ifdef DEBUGPRINTS
#define DPRINTF printf
#else
#define DPRINTF
#endif


/***********************************************************************
** PRIVATE FUNCTION:    Test_Result
** DESCRIPTION: Used in conjunction with the regress tool, prints out the
**              status of the test case.
** INPUTS:      PASS/FAIL
** OUTPUTS:     None
** RETURN:      None
** SIDE EFFECTS:
**
** RESTRICTIONS:
**      None
** MEMORY:      NA
** ALGORITHM:   Determine what the status is and print accordingly.
**
***********************************************************************/


static void Test_Result (int result)
{
    switch (result)
    {
        case PASS:
            printf ("PASS\n");
            break;
        case FAIL:
            printf ("FAIL\n");
            failed_already = 1;
            break;
        default:
            break;
    }
}

static void do_work(void);

/* --- Server state functions --------------------------------------------- */
void
SetServerState(char *waiter, PRInt32 state)
{
    PR_Lock(ServerStateCVLock);
    ServerState = state;
    PR_NotifyCondVar(ServerStateCV);

    if (debug_mode) {
        DPRINTF("\t%s changed state to %d\n", waiter, state);
    }

    PR_Unlock(ServerStateCVLock);
}

int
WaitServerState(char *waiter, PRInt32 state)
{
    PRInt32 rv;

    PR_Lock(ServerStateCVLock);

    if (debug_mode) {
        DPRINTF("\t%s waiting for state %d\n", waiter, state);
    }

    while(!(ServerState & state)) {
        PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT);
    }
    rv = ServerState;

    if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n",
                                waiter, state, ServerState);
    PR_Unlock(ServerStateCVLock);

    return rv;
}

/* --- Server Functions ------------------------------------------- */

PRLock *workerThreadsLock;
PRInt32 workerThreads;
PRInt32 workerThreadsBusy;

void
WorkerThreadFunc(void *_listenSock)
{
    PRFileDesc *listenSock = (PRFileDesc *)_listenSock;
    PRInt32 bytesRead;
    PRInt32 bytesWritten;
    char *dataBuf;
    char *sendBuf;

    if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
                                _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32);
    dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32);
    if (!dataBuf)
        if (debug_mode) {
            printf("\tServer could not malloc space!?\n");
        }
    sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char));
    if (!sendBuf)
        if (debug_mode) {
            printf("\tServer could not malloc space!?\n");
        }

    if (debug_mode) {
        DPRINTF("\tServer worker thread running\n");
    }

    while(1) {
        PRInt32 bytesToRead = _client_data;
        PRInt32 bytesToWrite = _server_data;
        PRFileDesc *newSock;
        PRNetAddr *rAddr;
        PRInt32 loops = 0;

        loops++;

        if (debug_mode) {
            DPRINTF("\tServer thread going into accept\n");
        }

        bytesRead = PR_AcceptRead(listenSock,
                                  &newSock,
                                  &rAddr,
                                  dataBuf,
                                  bytesToRead,
                                  PR_INTERVAL_NO_TIMEOUT);

        if (bytesRead < 0) {
            if (debug_mode) {
                printf("\tServer error in accept (%d)\n", bytesRead);
            }
            continue;
        }

        if (debug_mode) {
            DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead);
        }

        PR_AtomicIncrement(&workerThreadsBusy);
        if (workerThreadsBusy == workerThreads) {
            PR_Lock(workerThreadsLock);
            if (workerThreadsBusy == workerThreads) {
                PRThread *WorkerThread;

                WorkerThread = PR_CreateThread(
                                   PR_SYSTEM_THREAD,
                                   WorkerThreadFunc,
                                   listenSock,
                                   PR_PRIORITY_NORMAL,
                                   ServerScope,
                                   PR_UNJOINABLE_THREAD,
                                   THREAD_STACKSIZE);

                if (!WorkerThread) {
                    if (debug_mode) {
                        printf("Error creating client thread %d\n", workerThreads);
                    }
                } else {
                    PR_AtomicIncrement(&workerThreads);
                    if (debug_mode) {
                        DPRINTF("\tServer creates worker (%d)\n", workerThreads);
                    }
                }
            }
            PR_Unlock(workerThreadsLock);
        }

        bytesToRead -= bytesRead;
        while (bytesToRead) {
            bytesRead = PR_Recv(newSock,
                                dataBuf,
                                bytesToRead,
                                0,
                                PR_INTERVAL_NO_TIMEOUT);
            if (bytesRead < 0) {
                if (debug_mode) {
                    printf("\tServer error receiving data (%d)\n", bytesRead);
                }
                continue;
            }
            if (debug_mode) {
                DPRINTF("\tServer received %d bytes\n", bytesRead);
            }
        }

        bytesWritten = PR_Send(newSock,
                               sendBuf,
                               bytesToWrite,
                               0,
                               PR_INTERVAL_NO_TIMEOUT);
        if (bytesWritten != _server_data) {
            if (debug_mode) printf("\tError sending data to client (%d, %d)\n",
                                       bytesWritten, PR_GetOSError());
        } else {
            if (debug_mode) {
                DPRINTF("\tServer sent %d bytes\n", bytesWritten);
            }
        }

        PR_Close(newSock);
        PR_AtomicDecrement(&workerThreadsBusy);
    }
}

PRFileDesc *
ServerSetup(void)
{
    PRFileDesc *listenSocket;
    PRSocketOptionData sockOpt;
    PRNetAddr serverAddr;
    PRThread *WorkerThread;

    if ((listenSocket = PR_NewTCPSocket()) == NULL) {
        if (debug_mode) {
            printf("\tServer error creating listen socket\n");
        }
        else {
            Test_Result(FAIL);
        }
        return NULL;
    }

    sockOpt.option = PR_SockOpt_Reuseaddr;
    sockOpt.value.reuse_addr = PR_TRUE;
    if (PR_SetSocketOption(listenSocket, &sockOpt) != PR_SUCCESS) {
        if (debug_mode) printf("\tServer error setting socket option: OS error %d\n",
                                   PR_GetOSError());
        else {
            Test_Result(FAIL);
        }
        PR_Close(listenSocket);
        return NULL;
    }

    memset(&serverAddr, 0, sizeof(PRNetAddr));
    serverAddr.inet.family = PR_AF_INET;
    serverAddr.inet.port = PR_htons(PORT);
    serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);

    if (PR_Bind(listenSocket, &serverAddr) != PR_SUCCESS) {
        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
                                   PR_GetOSError());
        else {
            Test_Result(FAIL);
        }
        PR_Close(listenSocket);
        return NULL;
    }

    if (PR_Listen(listenSocket, 128) != PR_SUCCESS) {
        if (debug_mode) {
            printf("\tServer error listening to server socket\n");
        }
        else {
            Test_Result(FAIL);
        }
        PR_Close(listenSocket);

        return NULL;
    }

    /* Create Clients */
    workerThreads = 0;
    workerThreadsBusy = 0;

    workerThreadsLock = PR_NewLock();

    WorkerThread = PR_CreateThread(
                       PR_SYSTEM_THREAD,
                       WorkerThreadFunc,
                       listenSocket,
                       PR_PRIORITY_NORMAL,
                       ServerScope,
                       PR_UNJOINABLE_THREAD,
                       THREAD_STACKSIZE);

    if (!WorkerThread) {
        if (debug_mode) {
            printf("error creating working thread\n");
        }
        PR_Close(listenSocket);
        return NULL;
    }
    PR_AtomicIncrement(&workerThreads);
    if (debug_mode) {
        DPRINTF("\tServer created primordial worker thread\n");
    }

    return listenSocket;
}

/* The main server loop */
void
ServerThreadFunc(void *unused)
{
    PRFileDesc *listenSocket;

    /* Do setup */
    listenSocket = ServerSetup();

    if (!listenSocket) {
        SetServerState(SERVER, SERVER_STATE_DEAD);
    } else {

        if (debug_mode) {
            DPRINTF("\tServer up\n");
        }

        /* Tell clients they can start now. */
        SetServerState(SERVER, SERVER_STATE_READY);

        /* Now wait for server death signal */
        WaitServerState(SERVER, SERVER_STATE_DYING);

        /* Cleanup */
        SetServerState(SERVER, SERVER_STATE_DEAD);
    }
}

/* --- Client Functions ------------------------------------------- */

PRInt32 numRequests;
PRInt32 numClients;
PRMonitor *clientMonitor;

void
ClientThreadFunc(void *unused)
{
    PRNetAddr serverAddr;
    PRFileDesc *clientSocket;
    char *sendBuf;
    char *recvBuf;
    PRInt32 rv;
    PRInt32 bytesNeeded;

    sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char));
    if (!sendBuf)
        if (debug_mode) {
            printf("\tClient could not malloc space!?\n");
        }
    recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char));
    if (!recvBuf)
        if (debug_mode) {
            printf("\tClient could not malloc space!?\n");
        }

    memset(&serverAddr, 0, sizeof(PRNetAddr));
    serverAddr.inet.family = PR_AF_INET;
    serverAddr.inet.port = PR_htons(PORT);
    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);

    while(numRequests > 0) {

        if ( (numRequests % 10) == 0 )
            if (debug_mode) {
                printf(".");
            }
        if (debug_mode) {
            DPRINTF("\tClient starting request %d\n", numRequests);
        }

        clientSocket = PR_NewTCPSocket();
        if (!clientSocket) {
            if (debug_mode) printf("Client error creating socket: OS error %d\n",
                                       PR_GetOSError());
            continue;
        }

        if (debug_mode) {
            DPRINTF("\tClient connecting\n");
        }

        rv = PR_Connect(clientSocket,
                        &serverAddr,
                        PR_INTERVAL_NO_TIMEOUT);
        if (!clientSocket) {
            if (debug_mode) {
                printf("\tClient error connecting\n");
            }
            continue;
        }

        if (debug_mode) {
            DPRINTF("\tClient connected\n");
        }

        rv = PR_Send(clientSocket,
                     sendBuf,
                     _client_data,
                     0,
                     PR_INTERVAL_NO_TIMEOUT);
        if (rv != _client_data) {
            if (debug_mode) {
                printf("Client error sending data (%d)\n", rv);
            }
            PR_Close(clientSocket);
            continue;
        }

        if (debug_mode) {
            DPRINTF("\tClient sent %d bytes\n", rv);
        }

        bytesNeeded = _server_data;
        while(bytesNeeded) {
            rv = PR_Recv(clientSocket,
                         recvBuf,
                         bytesNeeded,
                         0,
                         PR_INTERVAL_NO_TIMEOUT);
            if (rv <= 0) {
                if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n",
                                           rv, (_server_data - bytesNeeded), _server_data);
                break;
            }
            if (debug_mode) {
                DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv);
            }
            bytesNeeded -= rv;
        }

        PR_Close(clientSocket);

        PR_AtomicDecrement(&numRequests);
    }

    PR_EnterMonitor(clientMonitor);
    --numClients;
    PR_Notify(clientMonitor);
    PR_ExitMonitor(clientMonitor);

    PR_DELETE(sendBuf);
    PR_DELETE(recvBuf);
}

void
RunClients(void)
{
    PRInt32 index;

    numRequests = _iterations;
    numClients = _clients;
    clientMonitor = PR_NewMonitor();

    for (index=0; index<_clients; index++) {
        PRThread *clientThread;


        clientThread = PR_CreateThread(
                           PR_USER_THREAD,
                           ClientThreadFunc,
                           NULL,
                           PR_PRIORITY_NORMAL,
                           ClientScope,
                           PR_UNJOINABLE_THREAD,
                           THREAD_STACKSIZE);

        if (!clientThread) {
            if (debug_mode) {
                printf("\terror creating client thread %d\n", index);
            }
        } else if (debug_mode) {
            DPRINTF("\tMain created client %d/%d\n", index+1, _clients);
        }

    }

    PR_EnterMonitor(clientMonitor);
    while(numClients) {
        PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT);
    }
    PR_ExitMonitor(clientMonitor);
}

/* --- Main Function ---------------------------------------------- */

static
void do_work()
{
    PRThread *ServerThread;
    PRInt32 state;

    SetServerState(MAIN, SERVER_STATE_STARTUP);
    ServerThread = PR_CreateThread(
                       PR_USER_THREAD,
                       ServerThreadFunc,
                       NULL,
                       PR_PRIORITY_NORMAL,
                       ServerScope,
                       PR_JOINABLE_THREAD,
                       THREAD_STACKSIZE);
    if (!ServerThread) {
        if (debug_mode) {
            printf("error creating main server thread\n");
        }
        return;
    }

    /* Wait for server to be ready */
    state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD);

    if (!(state & SERVER_STATE_DEAD)) {
        /* Run Test Clients */
        RunClients();

        /* Send death signal to server */
        SetServerState(MAIN, SERVER_STATE_DYING);
    }

    PR_JoinThread(ServerThread);
}

static void do_workUU(void)
{
    ServerScope = PR_LOCAL_THREAD;
    ClientScope = PR_LOCAL_THREAD;
    do_work();
}

static void do_workUK(void)
{
    ServerScope = PR_LOCAL_THREAD;
    ClientScope = PR_GLOBAL_THREAD;
    do_work();
}

static void do_workKU(void)
{
    ServerScope = PR_GLOBAL_THREAD;
    ClientScope = PR_LOCAL_THREAD;
    do_work();
}

static void do_workKK(void)
{
    ServerScope = PR_GLOBAL_THREAD;
    ClientScope = PR_GLOBAL_THREAD;
    do_work();
}


static void Measure(void (*func)(void), const char *msg)
{
    PRIntervalTime start, stop;
    double d;

    start = PR_IntervalNow();
    (*func)();
    stop = PR_IntervalNow();

    d = (double)PR_IntervalToMicroseconds(stop - start);

    if (debug_mode) {
        printf("\n%40s: %6.2f usec\n", msg, d / _iterations);
    }
}


int main(int argc, char **argv)
{
    /* 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
    */
    PLOptStatus os;
    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
    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;
            default:
                break;
        }
    }
    PL_DestroyOptState(opt);

    /* main test */
    if (debug_mode) {
        printf("Enter number of iterations: \n");
        scanf("%d", &_iterations);
        printf("Enter number of clients   : \n");
        scanf("%d", &_clients);
        printf("Enter size of client data : \n");
        scanf("%d", &_client_data);
        printf("Enter size of server data : \n");
        scanf("%d", &_server_data);
    }
    else
    {

        _iterations = 10;
        _clients = 1;
        _client_data = 10;
        _server_data = 10;
    }

    if (debug_mode) {
        printf("\n\n%d iterations with %d client threads.\n",
               _iterations, _clients);
        printf("Sending %d bytes of client data and %d bytes of server data\n",
               _client_data, _server_data);
    }
    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    PR_STDIO_INIT();

    ServerStateCVLock = PR_NewLock();
    ServerStateCV = PR_NewCondVar(ServerStateCVLock);

    Measure(do_workUU, "server loop user/user");
#if 0
    Measure(do_workUK, "server loop user/kernel");
    Measure(do_workKU, "server loop kernel/user");
    Measure(do_workKK, "server loop kernel/kernel");
#endif

    PR_Cleanup();

    return failed_already;
}
