/*
 *------------------------------------------------------------------
 * Copyright (c) 2005-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 <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <gtk/gtk.h>
#include "g2.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

/*
 * globals
 */
boolean g_little_endian;
event_t *g_events;
ulong g_nevents;
pid_sort_t *g_pids;
pid_sort_t *g_original_pids;
int g_npids;
pid_data_t *g_pid_data_list;

/*
 * locals
 */
pid_data_t **s_pidhash;

/*
 * config parameters
 */

double ticks_per_ns=1000.0;
boolean ticks_per_ns_set;

/****************************************************************************
* event_init
****************************************************************************/

void event_init(void)
{
    ulong endian;
    char *ep;
    char *askstr;
    int tmp;

    ep = (char *)&endian;
    endian = 0x12345678;
    if (*ep != 0x12)
        g_little_endian = TRUE;
    else
        g_little_endian = FALSE;

    askstr = getprop("dont_ask_ticks_per_ns_initially");

    if (askstr && (*askstr == 't' || *askstr == 'T')) {
        tmp = atol(getprop_default("ticks_per_ns", 0));
        if (tmp > 0) {
            ticks_per_ns = tmp;
            ticks_per_ns_set = TRUE;
        }
    }
}

/****************************************************************************
* find_or_add_pid
****************************************************************************/

pid_data_t *find_or_add_pid (ulong pid)
{
    pid_data_t *pp;
    ulong bucket;

    bucket = pid % PIDHASH_NBUCKETS;

    pp = s_pidhash[bucket];

    if (pp == 0) {
        pp = g_malloc0(sizeof(pid_data_t));
        pp->pid_value = pid;
        s_pidhash[bucket] = pp;
        g_npids++;
        return(pp);
    }
    while (pp) {
        if (pp->pid_value == pid)
            return(pp);
        pp = pp->next;
    }

    pp = g_malloc0(sizeof(pid_data_t));
    pp->pid_value = pid;
    pp->next = s_pidhash[bucket];
    s_pidhash[bucket] = pp;
    g_npids++;
    return(pp);
}

/****************************************************************************
* pid_cmp
****************************************************************************/

int pid_cmp(const void *a1, const void *a2)
{
    pid_sort_t *p1 = (pid_sort_t *)a1;
    pid_sort_t *p2 = (pid_sort_t *)a2;

    if (p1->pid_value < p2->pid_value)
        return(-1);
    else if (p1->pid_value == p2->pid_value)
        return(0);
    else
        return(1);
}

/****************************************************************************
* make_sorted_pid_vector
****************************************************************************/

static void make_sorted_pid_vector(void)
{
    pid_data_t *pp;
    pid_data_t **p_previous;
    pid_sort_t *psp;
    int i;

    psp = g_pids = g_malloc0(sizeof(pid_sort_t)*g_npids);

    for (i = 0; i < PIDHASH_NBUCKETS; i++) {
        pp = s_pidhash[i];
        while(pp) {
            psp->pid = pp;
            psp->pid_value = pp->pid_value;
            psp++;
            pp = pp->next;
        }
    }

    qsort(&g_pids[0], g_npids, sizeof(pid_sort_t), pid_cmp);

    /* put the sort order into the pid objects */
    psp = g_pids;

    /*
     * This is rather gross.
     *
     * We happen to know that whenever this function is called, the hash table
     * structure itself is immediately torn down. So the "next" pointers in the
     * pid_data_t elements are about to become useless.
     *
     * So we re-use them, to link all the pid_data_t elements together into a
     * single unified linked list, with g_pid_data_list pointing to the head.
     * This means we can walk all the pid_data_t objects if we really want to.
     * Reading snapshots from disk is one example.
     *
     * Alternatively we could just leave the hash table in place; this is
     * far nicer, but as it happens, trading O(n) lookups for O(1) lookups
     * isn't actually a problem for the restricted post-tear-down usage. So for
     * now we take the memory savings and swap our hash table for a list.
     */
    p_previous = &g_pid_data_list;
    for (i = 0; i < g_npids; i++) {
        pp = psp->pid;
        pp->pid_index = i;
        *p_previous = pp;
        p_previous = &pp->next;
        psp++;
    }
    *p_previous = NULL;

    /*
     * Squirrel away original (sorted) vector, so we can
     * toggle between "chase" mode, snapshots, and the original
     * display method on short notice
     */
    g_original_pids = g_malloc0(sizeof(pid_sort_t)*g_npids);
    memcpy (g_original_pids, g_pids, sizeof(pid_sort_t)*g_npids);
}

/****************************************************************************
* read_events
****************************************************************************/

void read_events(char *filename)
{
    ulong *ulp;
    ulong size;
    event_t *ep;
    raw_event_t *rep;
    ulonglong start_time=0ULL;
    ulonglong low_time;
    boolean once=TRUE;
    int i;
    char tmpbuf [128];

    ulp = (ulong *)mapfile(filename, &size);

    if (ulp == NULL) {
        snprintf(tmpbuf, sizeof(tmpbuf), "Couldn't open %s\n", filename);
        infobox("Read Event Log Failure", tmpbuf);
        return;
    }

    g_nevents = ntohl(*ulp);

    if (size != (g_nevents*sizeof(raw_event_t) + sizeof(g_nevents))) {
        snprintf(tmpbuf, sizeof(tmpbuf),
                 "%s was damaged, or isn't an event log.\n", filename);
        infobox("Bad Input File", tmpbuf);
        g_nevents = 0;
        unmapfile((char *)ulp, size);
        return;
    }

    rep = (raw_event_t *)(ulp+1);

    if (g_events)
        g_free(g_events);

    g_events = (event_t *)g_malloc(g_nevents * sizeof(event_t));
    ep = g_events;

    while (g_npids > 0) {
        g_free((g_pids + g_npids-1)->pid);
        g_npids--;
    }
    if (g_pids) {
        g_free(g_pids);
        g_free(g_original_pids);
        g_pids = 0;
        g_original_pids = 0;
    }

    s_pidhash = (pid_data_t **)g_malloc0(
        PIDHASH_NBUCKETS*sizeof(pid_data_t *));

    /* $$$ add a SEGV handler... */
    for (i = 0; i < g_nevents; i++) {
        if (once) {
            once = FALSE;
            start_time = ((ulonglong)ntohl(rep->time[0]));
            start_time <<= 32;
            low_time = ntohl(rep->time[1]);
            low_time &= 0xFFFFFFFF;
            start_time |= low_time;
            ep->time = 0LL;
        } else {
            ep->time = ((ulonglong)ntohl(rep->time[0]));
            ep->time <<= 32;
            low_time = ntohl(rep->time[1]);
            low_time &= 0xFFFFFFFF;
            ep->time |= low_time;
            ep->time -= start_time;
            ep->time /= ticks_per_ns;
        }
        ep->code = ntohl(rep->code);
        ep->pid = find_or_add_pid(ntohl(rep->pid));
        ep->datum = ntohl(rep->datum);
        ep->flags = 0;
        ep++;
        rep++;
    }

    unmapfile((char *)ulp, size);

    make_sorted_pid_vector();
    g_free(s_pidhash);
    s_pidhash = 0;

    /* Give the view-1 world a chance to reset a few things... */
    view1_read_events_callback();
}

static event_t *add_ep;

/****************************************************************************
* cpel_event_init
****************************************************************************/
void cpel_event_init (ulong nevents)
{
    g_nevents = nevents;
    if (g_events)
        g_free(g_events);
    add_ep = g_events = (event_t *)g_malloc(g_nevents * sizeof(event_t));
    while (g_npids > 0) {
        g_free((g_pids + g_npids-1)->pid);
        g_npids--;
    }
    if (g_pids) {
        g_free(g_pids);
        g_free(g_original_pids);
        g_pids = 0;
        g_original_pids = 0;
    }
    s_pidhash = (pid_data_t **)g_malloc0(
        PIDHASH_NBUCKETS*sizeof(pid_data_t *));
}

/****************************************************************************
* add_cpel_event
****************************************************************************/

void add_cpel_event(ulonglong delta, ulong track, ulong event, ulong datum)
{
    event_t *ep;

    ep = add_ep++;
    ep->time = delta;
    ep->pid = find_or_add_pid(track);
    ep->code = event;
    ep->datum = datum;
    ep->flags = 0;
}

/****************************************************************************
* add_clib_event
****************************************************************************/

void add_clib_event(double delta, unsigned short track,
                    unsigned short event, unsigned int index)
{
    event_t *ep;

    ep = add_ep++;
    ep->time = (ulonglong) (delta * 1e9); /* time in integer nanoseconds */
    ep->pid = find_or_add_pid(track);
    ep->code = event;
    ep->datum = index;
    ep->flags = EVENT_FLAG_CLIB;
}

/****************************************************************************
* cpel_event_finalize
****************************************************************************/

void cpel_event_finalize(void)
{
    make_sorted_pid_vector();
    g_free(s_pidhash);
    s_pidhash = 0;

    /* Give the view-1 world a chance to reset a few things... */
    view1_read_events_callback();
}

/****************************************************************************
* mapfile
****************************************************************************/

char *mapfile (char *file, ulong *sizep)
{
    struct stat statb;
    char *rv;
    int maphfile;
    size_t mapfsize;

    maphfile = open (file, O_RDONLY);

    if (maphfile < 0)
        return (NULL);

    if (fstat (maphfile, &statb) < 0) {
        return (NULL);
    }

    /* Don't try to mmap directories, FIFOs, semaphores, etc. */
    if (! (statb.st_mode & S_IFREG)) {
        return (NULL);
    }

    mapfsize = statb.st_size;

    if (mapfsize < 3) {
        close (maphfile);
        return (NULL);
    }

    rv = mmap (0, mapfsize, PROT_READ, MAP_SHARED, maphfile, 0);

    if (rv == 0) {
        g_error ("%s mapping problem, I quit...\n", file);
    }

    close (maphfile);

    if (madvise (rv, mapfsize, MADV_SEQUENTIAL) < 0) {
        return (rv);
    }

    if (sizep) {
        *sizep = mapfsize;
    }
    return (rv);
}

/****************************************************************************
* unmapfile
****************************************************************************/

boolean unmapfile (char *addr, ulong size)
{
    if (munmap (addr, size) < 0) {
        g_warning("Unmap error, addr 0x%lx size 0x%x\n",
                  (unsigned long) addr, (unsigned int)size);
        return(FALSE);
    }
    return(TRUE);
}

/****************************************************************************
* find_event_index
* Binary search for first event whose time is >= t
****************************************************************************/

int find_event_index (ulonglong t)
{
    int index, bottom, top;
    event_t *ep;

    bottom = g_nevents-1;
    top = 0;

    while (1) {
	index = (bottom + top) / 2;

        ep = (g_events + index);

        if (ep->time == t)
            return(index);

        if (top >= bottom) {
            while (index > 0 && ep->time > t) {
                ep--;
                index--;
            }
            while (index < g_nevents && ep->time < t) {
                ep++;
                index++;
            }
            return(index);
        }

        if (ep->time < t)
            top = index + 1;
        else
            bottom = index - 1;
    }
}

/****************************************************************************
* events_about
****************************************************************************/

void events_about (char *tmpbuf)
{
    snprintf(tmpbuf+strlen(tmpbuf), 1024 - strlen(tmpbuf),
             "%d total events, %.3f ticks per us\n",
             (int)g_nevents, ticks_per_ns);
}
