/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the Netscape Portable Runtime (NSPR).
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "nspr.h"

#include "plgetopt.h"

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


#ifndef IOV_MAX
#define IOV_MAX 16
#endif

#define BASE_PORT 9867

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


