/* 
 *------------------------------------------------------------------
 * 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->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);
}
