/*
 *------------------------------------------------------------------
 * Copyright (c) 2006-2016 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <ctype.h>
#include <vppinfra/clib.h>
#include <vppinfra/vec.h>
#include <vppinfra/hash.h>
#include <vppinfra/elog.h>
#include <vppinfra/mem.h>
#include <pwd.h>
#include <stdarg.h>
#include <time.h>
#include "cpel.h"
#include "cpel_util.h"

static elog_main_t elog_main;

/*
 * convert_clib_file
 */
void convert_clib_file(char *clib_file)
{
    clib_error_t *error = 0;
    int i;
    elog_main_t *em = &elog_main;
    double starttime, delta;

    error = elog_read_file (&elog_main, clib_file);

    if (error) {
        clib_warning("%U", format_clib_error, error);
        exit (1);
    }

    em = &elog_main;

    starttime = em->events[0].time;

    for (i = 0; i < vec_len (em->events); i++) {
        elog_event_t *e;        /* clib event */
        evt_t *ep;              /* xxx2cpel event */
        u8 *s;
        u64 timestamp;
        elog_event_type_t *t;
        u8 *brief_event_name;
        u8 *track_name;
        int j;

        e = vec_elt_at_index(em->events, i);

        /* Seconds since start of log */
        delta = e->time - starttime;

        /* u64 nanoseconds since start of log */
        timestamp = delta * 1e9;

        s = format (0, "%U%c", format_elog_event, em, e, 0);

        /* allocate an event instance */
        vec_add2(the_events, ep, 1);
        ep->timestamp = timestamp;

        /* convert string event code to a real number */
        t = vec_elt_at_index (em->event_types, e->event_type);

        /*
         * Construct a reasonable event name.
         * Truncate the format string at the first whitespace break
         * or printf format character.
         */
        brief_event_name = format (0, "%s", t->format);

        for (j = 0; j < vec_len (brief_event_name); j++) {
            if (brief_event_name[j] == ' ' ||
                brief_event_name[j] == '%' ||
                brief_event_name[j] == '(') {
                brief_event_name[j] = 0;
                break;
            }
        }
        /* Throw away that much of the formatted event */
        vec_delete (s, j+1, 0);

        ep->event_id = find_or_add_event(brief_event_name, "%s");

        track_name = format (0, "%U%c", format_elog_track_name, em, e, 0);

        ep->track_id = find_or_add_track (track_name);

        ep->datum = find_or_add_strtab(s);

        vec_free (track_name);
        vec_free(brief_event_name);
        vec_free(s);
    }
}

u8 *vec_basename (char *s)
{
    u8 * rv;
    char *cp = s;

    while (*cp)
        cp++;

    cp--;

    while (cp > s && *cp != '/')
        cp--;

    if (cp > s)
        cp++;

    rv = format (0, "%s", cp);
    return rv;
}


int event_compare (const void *a0, const void *a1)
{
    evt_t *e0 = (evt_t *)a0;
    evt_t *e1 = (evt_t *)a1;

    if (e0->timestamp < e1->timestamp)
        return -1;
    else if (e0->timestamp > e1->timestamp)
        return 1;
    return 0;
}

int main (int argc, char **argv)
{
    int curarg=1;
    char **inputfiles = 0;
    char *outputfile = 0;
    FILE *ofp;

    clib_mem_init_thread_safe (0, 256 << 20);

    if (argc < 3)
        goto usage;

    while (curarg < argc) {
        if (!strncmp(argv[curarg], "--input-file", 3)) {
            curarg++;
            if (curarg < argc) {
                vec_add1 (inputfiles, argv[curarg]);
                curarg++;
                continue;
            }
            clib_warning("Missing filename after --input-file\n");
            exit (1);
        }

        if (!strncmp(argv[curarg], "--output-file", 3)) {
            curarg ++;
            if (curarg < argc) {
                outputfile = argv[curarg];
                curarg ++;
                continue;
            }
            clib_warning("Missing filename after --output-file\n");
            exit(1);
        }
        vec_add1 (inputfiles, argv[curarg]);
        curarg++;
        continue;

    usage:
        fformat(stderr,
                "c2cpel [--input-file] <filename> --output-file <filename>\n");
        exit(1);
    }

    if (vec_len(inputfiles) == 0 || outputfile == 0)
        goto usage;

    if (vec_len(inputfiles) > 1)
        goto usage;

    clib_mem_init (0, ((uword)3<<30));

    cpel_util_init();

    convert_clib_file (inputfiles[0]);

    ofp = fopen (outputfile, "w");
    if (ofp == NULL) {
        clib_unix_warning ("couldn't create %s", outputfile);
        exit (1);
    }

    alpha_sort_tracks();
    fixup_event_tracks();

    /*
     * Four sections: string-table, event definitions, track defs, events.
     */
    if (!write_cpel_header(ofp, 4)) {
        clib_warning ("Error writing cpel header to %s...\n", outputfile);
        unlink(outputfile);
        exit(1);
    }

    if (!write_string_table(ofp)) {
        clib_warning ("Error writing string table to %s...\n", outputfile);
        unlink(outputfile);
        exit(1);
    }

    if (!write_event_defs(ofp)) {
        clib_warning ("Error writing event defs to %s...\n", outputfile);
        unlink(outputfile);
        exit(1);
    }

    if (!write_track_defs(ofp)) {
        clib_warning ("Error writing track defs to %s...\n", outputfile);
        unlink(outputfile);
        exit(1);
    }

    if (!write_events(ofp, (u64) 1e9)) {
        clib_warning ("Error writing events to %s...\n", outputfile);
        unlink(outputfile);
        exit(1);

    }
    fclose(ofp);
    exit (0);
}
