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

#include "nspr.h"

#include "plgetopt.h"

#include <stdlib.h>
#include <string.h>


#ifndef IOV_MAX
#define IOV_MAX 16
#endif

#ifdef DEBUG
#define PORT_INC_DO +100
#else
#define PORT_INC_DO
#endif
#ifdef IS_64
#define PORT_INC_3264 +200
#else
#define PORT_INC_3264
#endif

#define BASE_PORT 9867 PORT_INC_DO PORT_INC_3264

int PR_CALLBACK Writev(int argc, char **argv)
{

    PRStatus rv;
    PRNetAddr serverAddr;
    PRFileDesc *clientSock, *debug = NULL;

    char *buffer = NULL;
    PRIOVec *iov = NULL;
    PRBool passed = PR_TRUE;
    PRIntervalTime timein, elapsed, timeout;
    PRIntervalTime tmo_min = 0x7fffffff, tmo_max = 0, tmo_elapsed = 0;
    PRInt32 tmo_counted = 0, iov_index, loop, bytes, number_fragments;
    PRInt32 message_length = 100, fragment_length = 100, messages = 100;
    struct Descriptor {
        PRInt32 length;
        PRUint32 checksum;
    } descriptor;

    /*
     * USAGE
     * -h       dns name of host serving the connection (default = self)
     * -m       number of messages to send              (default = 100)
     * -s       size of each message                    (default = 100)
     * -f       size of each message fragment           (default = 100)
     */

    PLOptStatus os;
    PLOptState *opt = PL_CreateOptState(argc, argv, "dh:m:s:f:");

    PR_STDIO_INIT();
    rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &serverAddr);
    PR_ASSERT(PR_SUCCESS == rv);

    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
        if (PL_OPT_BAD == os) {
            continue;
        }
        switch (opt->option)
        {
            case 'h':  /* the remote host */
            {
                PRIntn es = 0;
                PRHostEnt host;
                char buffer[1024];
                (void)PR_GetHostByName(opt->value, buffer, sizeof(buffer), &host);
                es = PR_EnumerateHostEnt(es, &host, BASE_PORT, &serverAddr);
                PR_ASSERT(es > 0);
            }
            break;
            case 'd':  /* debug mode */
                debug = PR_GetSpecialFD(PR_StandardError);
                break;
            case 'm':  /* number of messages to send */
                messages = atoi(opt->value);
                break;
            case 's':  /* total size of each message */
                message_length = atoi(opt->value);
                break;
            case 'f':  /* size of each message fragment */
                fragment_length = atoi(opt->value);
                break;
            default:
                break;
        }
    }
    PL_DestroyOptState(opt);

    buffer = (char*)malloc(message_length);

    number_fragments = (message_length + fragment_length - 1) / fragment_length + 1;
    while (IOV_MAX < number_fragments)
    {
        fragment_length = message_length / (IOV_MAX - 2);
        number_fragments = (message_length + fragment_length - 1) /
                           fragment_length + 1;
        if (NULL != debug) PR_fprintf(debug,
                                          "Too many fragments - reset fragment length to %ld\n", fragment_length);
    }
    iov = (PRIOVec*)malloc(number_fragments * sizeof(PRIOVec));

    iov[0].iov_base = (char*)&descriptor;
    iov[0].iov_len = sizeof(descriptor);
    for (iov_index = 1; iov_index < number_fragments; ++iov_index)
    {
        iov[iov_index].iov_base = buffer + (iov_index - 1) * fragment_length;
        iov[iov_index].iov_len = fragment_length;
    }

    for (bytes = 0; bytes < message_length; ++bytes) {
        buffer[bytes] = (char)bytes;
    }

    timeout = PR_SecondsToInterval(1);

    for (loop = 0; loop < messages; ++loop)
    {
        if (NULL != debug) {
            PR_fprintf(debug, "[%d]socket ... ", loop);
        }
        clientSock = PR_NewTCPSocket();
        if (clientSock)
        {
            timein = PR_IntervalNow();
            if (NULL != debug) {
                PR_fprintf(debug, "connecting ... ");
            }
            rv = PR_Connect(clientSock, &serverAddr, timeout);
            if (PR_SUCCESS == rv)
            {
                descriptor.checksum = 0;
                descriptor.length = (loop < (messages - 1)) ? message_length : 0;
                if (0 == descriptor.length) {
                    number_fragments = 1;
                }
                else
                    for (iov_index = 0; iov_index < descriptor.length; ++iov_index)
                    {
                        PRUint32 overflow = descriptor.checksum & 0x80000000;
                        descriptor.checksum = (descriptor.checksum << 1);
                        if (0x00000000 != overflow) {
                            descriptor.checksum += 1;
                        }
                        descriptor.checksum += buffer[iov_index];
                    }
                if (NULL != debug) PR_fprintf(
                        debug, "sending %d bytes ... ", descriptor.length);

                /* then, at the last moment ... */
                descriptor.length = PR_ntohl(descriptor.length);
                descriptor.checksum = PR_ntohl(descriptor.checksum);

                bytes = PR_Writev(clientSock, iov, number_fragments, timeout);
                if (NULL != debug) {
                    PR_fprintf(debug, "closing ... ");
                }
                rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH);
                rv = PR_Close(clientSock);
                if (NULL != debug) PR_fprintf(
                        debug, "%s\n", ((PR_SUCCESS == rv) ? "good" : "bad"));
                elapsed = PR_IntervalNow() - timein;
                if (elapsed < tmo_min) {
                    tmo_min = elapsed;
                }
                else if (elapsed > tmo_max) {
                    tmo_max = elapsed;
                }
                tmo_elapsed += elapsed;
                tmo_counted += 1;
            }
            else
            {
                if (NULL != debug) PR_fprintf(
                        debug, "failed - retrying (%d, %d)\n",
                        PR_GetError(), PR_GetOSError());
                PR_Close(clientSock);
            }
        }
        else if (NULL != debug)
        {
            PR_fprintf(debug, "unable to create client socket\n");
            passed = PR_FALSE;
        }
    }
    if (NULL != debug) {
        if (0 == tmo_counted) {
            PR_fprintf(debug, "No connection made\n");
        } else {
            PR_fprintf(
                debug, "\nTimings: %d [%d] %d (microseconds)\n",
                PR_IntervalToMicroseconds(tmo_min),
                PR_IntervalToMicroseconds(tmo_elapsed / tmo_counted),
                PR_IntervalToMicroseconds(tmo_max));
        }
    }

    PR_DELETE(buffer);
    PR_DELETE(iov);

    PR_fprintf(
        PR_GetSpecialFD(PR_StandardError),
        "%s\n", (passed) ? "PASSED" : "FAILED");
    return (passed) ? 0 : 1;
}

int main(int argc, char **argv)
{
    return (PR_VersionCheck(PR_VERSION)) ?
           PR_Initialize(Writev, argc, argv, 4) : -1;
}  /* main */

/* writev.c */


