/* 
 *------------------------------------------------------------------
 * 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/bitmap.h>
#include <vppinfra/byte_order.h>
#include <pwd.h>
#include <stdarg.h>
#include <time.h>
#include "cpel.h"
#include "cpel_util.h"

evt_t *the_events;

track_t *the_tracks;
u32 *track_alpha_map;

event_definition_t *the_event_definitions;
i64 min_timestamp;

/* Hash tables, used to find previous instances of the same items */
uword *the_track_hash;
uword *the_msg_event_hash;
uword *the_strtab_hash;
uword *the_pidtid_hash;
uword *the_pid_to_name_hash;
u8 *the_strtab;

uword *the_event_id_bitmap;

/*
 * find_or_add_strtab
 * Finds or adds a string to the string table
 */
u32 find_or_add_strtab(void *s_arg)
{
    uword *p;
    int len;
    u8 *this_string;
    u8 *scopy=0;
    char *s = s_arg;

    p = hash_get_mem(the_strtab_hash, s);
    if (p) {
        return (p[0]);
    }

    /*
     * Here's a CLIB bear-trap. We can't add the string-table 
     * strings to the to the hash table (directly), since it 
     * expands and moves periodically. All of the hash table
     * entries turn into dangling references, yadda yadda. 
     */

    len = strlen(s)+1;
    vec_add2(the_strtab, this_string, len);
    memcpy(this_string, s, len);
    
    /* Make a copy which won't be moving around... */
    vec_validate(scopy, len);
    memcpy(scopy, s, len);

    hash_set_mem(the_strtab_hash, scopy, this_string - the_strtab);

    return(this_string - the_strtab);
}

/*
 * find_or_add_track
 * returns index in track table
 */
u32 find_or_add_track(void *s_arg)
{
    uword *p;
    track_t *this_track;
    u8 *copy_s;
    char *s=s_arg;

    p = hash_get_mem(the_track_hash, s);
    if (p) {
        return (p[0]);
    }
    vec_add2(the_tracks, this_track, 1);

    this_track->original_index = this_track - the_tracks;
    this_track->strtab_offset = find_or_add_strtab(s);

    copy_s = (u8 *)vec_dup(s);

    hash_set_mem(the_track_hash, copy_s, this_track - the_tracks);
    return(this_track - the_tracks);
}

/* 
 * find_or_add_event
 * Adds an event to the event definition vector and add it to
 * the event hash table
 */

u32 find_or_add_event(void *s_arg, char *datum_format)
{
    uword *p;
    u8 *copy_s;
    event_definition_t *this_event_definition;
    u32 event_id;
    char *s=s_arg;

    p = hash_get_mem(the_msg_event_hash, s);
    if (p) {
        return (p[0]);
    }
    vec_add2(the_event_definitions, this_event_definition, 1);

    /* Allocate a new event-id */
    event_id = clib_bitmap_first_clear (the_event_id_bitmap);
    the_event_id_bitmap = clib_bitmap_set(the_event_id_bitmap, event_id, 1);
    this_event_definition->event = event_id;
    this_event_definition->event_format = find_or_add_strtab(s);
    this_event_definition->datum_format = find_or_add_strtab(datum_format);

    copy_s = (u8 *)vec_dup(s);

    hash_set_mem(the_msg_event_hash, copy_s, event_id);

    return(event_id);
}

/*
 * write_string_table
 */
int write_string_table(FILE *ofp)
{
    cpel_section_header_t sh;

    /* Round up string table size */
    while (vec_len(the_strtab) & 0x7)
        vec_add1(the_strtab, 0);

    sh.section_type = ntohl(CPEL_SECTION_STRTAB);
    sh.data_length = ntohl(vec_len(the_strtab));
    
    if (fwrite(&sh, sizeof(sh), 1, ofp) != 1)
        return(0);
    
    if (fwrite(the_strtab, 1, vec_len(the_strtab), ofp) != 
        vec_len(the_strtab))
        return(0);

    return(1);
}

/*
 * write_cpel_header
 */
int write_cpel_header(FILE *ofp, u32 nsections)
{
    cpel_file_header_t h;
    
    h.endian_version = CPEL_FILE_VERSION;
    h.pad = 0; 
    h.nsections = ntohs(nsections);
    h.file_date = ntohl(time(0));
    if (fwrite(&h, sizeof(h), 1, ofp) != 1)
        return (0);

    return(1);
}

/* 
 * write_event_defs
 */
int write_event_defs(FILE *ofp)
{
    cpel_section_header_t sh;
    event_definition_section_header_t edsh;
    event_definition_t *this_event_definition;
    int i;

    /* Next, the event definitions */
    sh.section_type = ntohl(CPEL_SECTION_EVTDEF);
    sh.data_length = ntohl(vec_len(the_event_definitions)
                           *sizeof(the_event_definitions[0]) 
                           + sizeof(event_definition_section_header_t));

    if (fwrite(&sh, sizeof(sh), 1, ofp) != 1)
        return(0);

    memset(&edsh, 0, sizeof(edsh));

    strcpy(edsh.string_table_name, "FileStrtab");
    edsh.number_of_event_definitions = ntohl(vec_len(the_event_definitions));
    
    if (fwrite(&edsh, sizeof(edsh), 1, ofp) != 1)
        return(0);

    for (i = 0; i < vec_len(the_event_definitions); i++) {
        this_event_definition = &the_event_definitions[i];
        /* Endian fixup */
        this_event_definition->event = ntohl(this_event_definition->event);
        this_event_definition->event_format = 
            ntohl(this_event_definition->event_format);
        this_event_definition->datum_format =
            ntohl(this_event_definition->datum_format);

        if (fwrite(this_event_definition, sizeof(the_event_definitions[0]), 
                   1, ofp) != 1)
            return(0);
    }
    return(1);
}

/*
 * ntohll
 */
u64 ntohll (u64 x) {
    if (clib_arch_is_little_endian)
	x = ((((x >> 0) & 0xff) << 56)
	     | (((x >> 8) & 0xff) << 48)
	     | (((x >> 16) & 0xff) << 40)
	     | (((x >> 24) & 0xff) << 32)
	     | (((x >> 32) & 0xff) << 24)
	     | (((x >> 40) & 0xff) << 16)
	     | (((x >> 48) & 0xff) << 8)
	     | (((x >> 56) & 0xff) << 0));
    
    return x;
}

/* 
 * write_events
 */
int write_events(FILE *ofp, u64 clock_ticks_per_second)
{
    cpel_section_header_t sh;
    event_section_header_t eh;
    u32 number_of_events;
    int i;
    event_entry_t e;
    u64 net_timestamp;
    evt_t *this_event;
    u32 time0, time1;

    number_of_events = vec_len(the_events);

    sh.section_type = ntohl(CPEL_SECTION_EVENT);
    sh.data_length = ntohl(number_of_events * sizeof(e) +
                           sizeof(event_section_header_t));

    if (fwrite(&sh, sizeof(sh), 1, ofp) != 1)
        return(0);
    
    memset(&eh, 0, sizeof(eh));
    strcpy(eh.string_table_name, "FileStrtab");
    eh.number_of_events = ntohl(number_of_events);
    eh.clock_ticks_per_second = ntohl(clock_ticks_per_second);
    
    if (fwrite(&eh, sizeof(eh), 1, ofp) != 1)
        return(0);

    for (i = 0; i < number_of_events; i++) {
        this_event = &the_events[i];
        net_timestamp = ntohll(this_event->timestamp);
    
        time1 = net_timestamp>>32;
        time0 = net_timestamp & 0xFFFFFFFF;
        
        e.time[0] = time0;
        e.time[1] = time1;
        e.track = ntohl(this_event->track_id);
        e.event_code = ntohl(this_event->event_id);
        e.event_datum = ntohl(this_event->datum);
        
        if (fwrite(&e, sizeof(e), 1, ofp) != 1)
            return(0);
    }
    return(1);
}

/*
 * write_track_defs
 */
int write_track_defs(FILE *ofp)
{
    cpel_section_header_t sh;
    track_definition_section_header_t tdsh;
    track_definition_t record;
    track_definition_t *this_track_definition = &record;
    int i;
    event_definition_section_header_t edsh;

    /* Next, the event definitions */
    sh.section_type = ntohl(CPEL_SECTION_TRACKDEF);
    sh.data_length = ntohl(vec_len(the_tracks)
                           *sizeof(this_track_definition[0]) 
                           + sizeof(track_definition_section_header_t));

    if (fwrite(&sh, sizeof(sh), 1, ofp) != 1)
        return(0);

    memset(&tdsh, 0, sizeof(tdsh));

    strcpy(tdsh.string_table_name, "FileStrtab");
    tdsh.number_of_track_definitions = ntohl(vec_len(the_tracks));
    
    if (fwrite(&tdsh, sizeof(edsh), 1, ofp) != 1)
        return(0);

    for (i = 0; i < vec_len(the_tracks); i++) {
        this_track_definition->track = ntohl(i);
        this_track_definition->track_format = 
            ntohl(the_tracks[i].strtab_offset);

        if (fwrite(this_track_definition, sizeof(this_track_definition[0]),
                   1, ofp) != 1)
            return(0);
    }
    return(1);
}

void cpel_util_init (void)
{
    u8 *eventstr;

    the_strtab_hash = hash_create_string (0, sizeof (uword));
    the_msg_event_hash = hash_create_string (0, sizeof (uword));
    the_track_hash = hash_create_string (0, sizeof (uword));
    the_pidtid_hash = hash_create_string (0, sizeof(uword));
    the_pid_to_name_hash = hash_create(0, sizeof(uword));
    
    /* Must be first, or no supper... */
    find_or_add_strtab("FileStrtab");

    /* Historical canned events, no longer used. */
    if (0) {
        /* event 0 (not used) */
        eventstr = format(0, "PlaceholderNotUsed");
        vec_add1(eventstr, 0);
        find_or_add_event(eventstr, "%s");
        vec_free(eventstr);
        
        /* event 1 (thread on CPU) */
        eventstr = format(0, "THREAD/THRUNNING");
        vec_add1(eventstr, 0);
        find_or_add_event(eventstr, "%s");
        vec_free(eventstr);
        
        /* event 2 (thread ready) */
        eventstr = format(0, "THREAD/THREADY");
        vec_add1(eventstr, 0);
        find_or_add_event(eventstr, "%s");
        vec_free(eventstr);
        
        /* event 3 (function enter) */
        eventstr = format(0, "FUNC/ENTER");
        vec_add1(eventstr, 0);
        find_or_add_event(eventstr, "0x%x");
        vec_free(eventstr);
        
        /* event 4 (function enter) */
        eventstr = format(0, "FUNC/EXIT");
        vec_add1(eventstr, 0);
        find_or_add_event(eventstr, "0x%x");
        vec_free(eventstr);
    }
}

/*
 * alpha_compare_tracks
 */
static int alpha_compare_tracks(const void *a1, const void *a2)
{
    int i;
    track_t *t1 = (track_t *)a1;
    track_t *t2 = (track_t *)a2;
    u8 *s1 = &the_strtab[t1->strtab_offset];
    u8 *s2 = &the_strtab[t2->strtab_offset];

    for (i = 0; s1[i] && s2[i]; i++) {
        if (s1[i] < s2[i])
            return(-1);
        if (s1[i] > s2[i])
            return(1);
    }
    return(0);
}

/*
 * alpha_sort_tracks
 * Alphabetically sort tracks, set up a mapping
 * vector so we can quickly map the original track index to
 * the new/improved/alpha-sorted index
 */
void alpha_sort_tracks(void)
{
    track_t *this_track;
    int i;

    qsort(the_tracks, vec_len(the_tracks), sizeof(track_t),
          alpha_compare_tracks);

    vec_validate(track_alpha_map, vec_len(the_tracks));
    _vec_len(track_alpha_map) = vec_len(the_tracks);

    for (i = 0; i < vec_len(the_tracks); i++) {
        this_track = &the_tracks[i];
        track_alpha_map[this_track->original_index] = i;
    }
}

/*
 * fixup_event_tracks
 * Use the track alpha mapping to account for the alphabetic
 * sort performed by the previous routine
 */
void fixup_event_tracks(void)
{
    int i;
    u32 old_track;

    for (i = 0; i < vec_len(the_events); i++) {
        old_track = the_events[i].track_id;
        the_events[i].track_id = track_alpha_map[old_track];
    }
}

/* Indispensable for debugging in gdb... */

u32 vl(void *x)
{
    return vec_len(x);
}
