/* rsyslog testbench tool to mangle .qi files
 *
 * Copyright (C) 2016 by Rainer Gerhards
 * Released uner ASL 2.0
 */
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>

static int debug = 0;

void usage(void) {
    fprintf(stderr,
            "mangle_qi -d -q <.qi-file>\n"
            "-d enables debug messages\n");
    exit(1);
}

void processQI(FILE *const __restrict__ qi) {
    char lnbuf[4096];
    char propname[64];
    int rectype;
    int length;
    int queuesize;
    int i;
    int c;
    (void)fgets(lnbuf, sizeof(lnbuf), qi);
    fputs(lnbuf, stdout);
    /* we now read the queue size line */
    /* note: this is quick and dirty, no error checks
     * are done!
     */
    fgetc(qi); /* skip '+' */
    for (i = 0; (c = fgetc(qi)) != ':'; ++i) {
        propname[i] = c;
    }
    propname[i] = '\0';
    if (strcmp(propname, "iQueueSize")) {
        fprintf(stderr,
                ".qi file format unknown: line 2 does "
                "not contain iQueueSize property, instead '%s'\n",
                propname);
        exit(1);
    }

    rectype = 0;
    for (c = fgetc(qi); isdigit(c); c = fgetc(qi)) rectype = rectype * 10 + c - '0';

    length = 0;
    for (c = fgetc(qi); isdigit(c); c = fgetc(qi)) length = length * 10 + c - '0';

    queuesize = 0;
    for (c = fgetc(qi); isdigit(c); c = fgetc(qi)) queuesize = queuesize * 10 + c - '0';

    int maxval_for_length = 10;
    for (i = 1; i < length; ++i) maxval_for_length *= 10; /* simulate int-exp() */

    if (debug) {
        fprintf(stderr, "rectype: %d\n", rectype);
        fprintf(stderr, "length: %d\n", length);
        fprintf(stderr, "queuesize: %d\n", queuesize);
        fprintf(stderr, "maxval_for_length: %d\n", maxval_for_length);
    }

    queuesize += 1; /* fake invalid queue size */
    if (queuesize > maxval_for_length) ++length;

    /* ready to go, write mangled queue size */
    printf("+%s:%d:%d:%d:", propname, rectype, length, queuesize);
    /* copy rest of file */
    while ((c = fgetc(qi)) != EOF) putchar(c);
}

int main(int argc, char *argv[]) {
    char *qifile = NULL;
    FILE *qi;
    int opt;
    while ((opt = getopt(argc, argv, "dq:")) != -1) {
        switch (opt) {
            case 'q':
                qifile = optarg;
                break;
            case 'd':
                debug = 1;
                break;
            default:
                usage();
                break;
        }
    }

    if (qifile == NULL) {
        fprintf(stderr, "ERROR: -q option MUST be specified\n");
        usage();
    }

    if ((qi = fopen(qifile, "r")) == NULL) {
        perror(qifile);
        exit(1);
    }
    processQI(qi);
    return 0;
}
