/**
 * TestLab main driver: simulation implementation.
 *
 * @copyright 2008, Research In Motion Ltd.
 *
 * @version $Id: //depot/main/dsp/ecall/c/testlab/testlab_sim.c#8 $
 */

#include <stdlib.h>

#include "rimtypes.h"
#include "ipc.h"
#include "error.h"
#include "control.h"
#include "option.h"

static char *options[] = {
    "--logpcm:%s",
    "--logpcm",
    "--log:%s",
    "--startframe:%s",
    "--totalframes:%s",
    "--campaign:%s",
    "-h",
    "--help",
    NULL
};

#define ARG_MAX_LENGTH  (200)
#define PORT_MAX_LENGTH (200)
#define HOST_MAX_LENGTH (200)
#define FILE_MAX_LENGTH (200)

static char p1[ARG_MAX_LENGTH];

static char *pcm                               = NULL;
static char pcmFile[FILE_MAX_LENGTH + 1]       = "";
static char logFile[FILE_MAX_LENGTH + 1]       = "";
static char campaignFile[FILE_MAX_LENGTH + 1]  = "";
static int  startFrame                         = 0;
static int  totalFrames                        = 0;

static void Usage(char *msg, ...) {
    va_list args;
    va_start(args, msg);

    if (msg != NULL) {
        fprintf(stderr, "Error: ");
        vfprintf(stderr, msg, args);
        fprintf(stderr, "\n");
    }

    fprintf(stderr, "Usage:\n");
    fprintf(stderr, "  testsim_demo <options>\n");
    fprintf(stderr, " with <options> in:\n");
    fprintf(stderr, " --logpcm[:fileBase]\n");
    fprintf(stderr, "   Logs UL in/out and DL in/out PCM samples\n");
    fprintf(stderr, "   Default fileBase is pcm.\n");
    fprintf(stderr, "   PCM file name template: fileBase<src><index>.pcm\n");
    fprintf(stderr, " --log:file\n");
    fprintf(stderr, "   Sets output log file to file.\n");
    fprintf(stderr, "   Default is results.txt.\n");
    fprintf(stderr, "   [stdout] and [stderr] can be used to send output to\n");
    fprintf(stderr, "   stdout and stderr streams.\n");
    fprintf(stderr, " --startframe:n\n");
    fprintf(stderr, "   Set the number of frames to process before sending\n");
    fprintf(stderr, "   the MsgPsapTx signal to the PSAP.\n");
    fprintf(stderr, "   Default is 10 frames (200 ms).\n");
    fprintf(stderr, " --totalframes:n\n");
    fprintf(stderr, "   Set the number of frames to wait for the MsgPsapRx\n");
    fprintf(stderr, "   signal before declaring a tomeout for a given\n");
    fprintf(stderr, "   transmission.  Default is 200*50 frames (200 s).\n");
    fprintf(stderr, " --campaign:file\n");
    fprintf(stderr, "   Sets input campaign file to file.\n");
    fprintf(stderr, "   Default is campaign.txt\n");

    va_end(args);
}

static int ProcessArgs(int argc, char *argv[]) {
    while (argc-- > 0) {
        int n;

        if (strlen(*argv) >= ARG_MAX_LENGTH) {
            Usage("Arguement too long <%s>", *argv);
            return FALSE;
        }
       
        n = option(*argv, options, p1);

        switch (n) {
            case 0: strcpy(pcmFile, p1); pcm = pcmFile; break;
            case 1: pcm = pcmFile; break;
            case 2: strcpy(logFile, p1); break;
            case 3: if (sscanf(p1, "%d", &startFrame) != 1) {
                         Usage("Invalid startFrame count %s", p1);
                         return FALSE;
                     }
                     break;
            case 4: if (sscanf(p1, "%d", &totalFrames) != 1) {
                         Usage("Invalid totalFrames count <%s>", p1);
                         return FALSE;
                     }
                     break;
            case 5: strcpy(campaignFile, p1); break;
            case 6:
            case 7: Usage(NULL); return FALSE;
            default: Usage("Invalid option %s", *argv); return FALSE;
        }
        argv++;
    }

    if (strlen(pcmFile)      <= 0) strcpy(pcmFile,       "pcm");
    if (strlen(logFile)      <= 0) strcpy(logFile,       "results.txt");
    if (strlen(campaignFile) <= 0) strcpy(campaignFile,  "campaign.txt");
    if (startFrame == 0)           startFrame = 10;
    if (totalFrames == 0)          totalFrames = 200 * 50;

    return TRUE;
}

int main(int argc, char *argv[]) {
    if (ProcessArgs(argc-1, &argv[1])) {
        LogInit(stderr);
        IpcInit();
        ControlInit("localhost", "10000", "10001", "10002", "10003",
                    pcm, campaignFile, logFile,
                    totalFrames + startFrame, startFrame);
        UlChannelInit("localhost", "10000");
        DlChannelInit("localhost", "10001");
        IvsInit("localhost", "10002");
        PsapInit("localhost", "10003");
        IpcStart();
        ControlRun();
        IpcStop();
        UlChannelFinal();
        DlChannelFinal();
        IpcFinal();
        return 0;
    }

    return -1;
}
