/*
 * Copyright (c) 2006 Atheros Communications Inc.
 * All rights reserved.
 * 
 *
 * 
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
//
 * 
 */

/* This tool parses the recevent logs stored in the binary format 
   by the wince athsrc */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <time.h>
#include <asm/types.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/types.h>
#include <linux/if.h>
#include <linux/wireless.h>
#include <a_config.h>
#include <a_osapi.h>
#include <a_types.h>
#include <athdefs.h>
#include <ieee80211.h>
#include <wmi.h>
#include <athdrv_linux.h>
#include <dbglog_api.h>

#undef DEBUG
#undef DBGLOG_DEBUG

#define ID_LEN                         2
#define FILENAME_LENGTH_MAX            128
#define DBGLOG_FILE                    "dbglog.h"
#define DBGLOGID_FILE                  "dbglog_id.h"
#define DBGLOG_OUTPUT_FILE             "dbglog.out"

const A_CHAR *progname;
A_CHAR dbglogfile[FILENAME_LENGTH_MAX];
A_CHAR dbglogidfile[FILENAME_LENGTH_MAX];
A_CHAR dbglogoutfile[FILENAME_LENGTH_MAX];
A_CHAR dbgloginfile[FILENAME_LENGTH_MAX];
FILE *fpout;
FILE *fpin;
int fmtlv;
int outfmt; /* 0: raw, 1: html 2: RTF */
int headerlen;
int noSystime;

A_CHAR dbglog_id_tag[DBGLOG_MODULEID_NUM_MAX][DBGLOG_DBGID_NUM_MAX][DBGLOG_DBGID_DEFINITION_LEN_MAX];

#define AR6K_MAX_DBG_BUFFER_SIZE 1500

struct dbg_binary_record {
    A_UINT32 ts;
    A_UINT32 length;
    A_UINT8  log[AR6K_MAX_DBG_BUFFER_SIZE];
};

struct dbg_binary_header {
    A_UINT8     sig;
    A_UINT8     ver;
    A_UINT16    len;
    A_UINT32    reserved;
};


#ifdef DEBUG
A_INT32 debugRecEvent = 0;
#define RECEVENT_DEBUG_PRINTF(args...)        if (debugRecEvent) printf(args);
#else
#define RECEVENT_DEBUG_PRINTF(args...)
#endif

static const A_CHAR htmlHeader[] = "<br/><style type='text/css'>\
.m0 { color:#ff0000; }\
.m1 { color:#0000FF; }\
.m2 { color:#8d8d8d; }\
.m3 { color:#000000; }\
.m4 { color:#a11693; }\
.m5 { color:#b452ab; }\
.m6 { color:#d18eca; }\
.m7 { color:#ff3205; }\
.m8 { color:#ff2428; }\
.m9 { color:#d700b4; }\
.m10 { color:#ffe20e; }\
.m11 { color:#ff0072; }\
.m12 { color:#00a700; }\
.m13 { color:#437197; }\
.m14 { color:#e64248; }\
.m15 { color:#5a1484; }\
</style>\n";

static const A_CHAR htmlFooter[] = "";

static const A_CHAR rtfHeader[] = "{\\rtf1\\ansi\\deff0{\\fonttbl\\f0\\fswiss Helvetica;}\n\
{\\colortbl \\red255\\green0\\blue0;\
\\red0\\green0\\blue255;\
\\red141\\green141\\blue141;\
\\red0\\green0\\blue0;\
\\red161\\green22\\blue147;\
\\red180\\green82\\blue171;\
\\red209\\green142\\blue202;\
\\red255\\green50\\blue5;\
\\red255\\green36\\blue40;\
\\red215\\green0\\blue180;\
\\red255\\green226\\blue14;\
\\red255\\green0\\blue114;\
\\red0\\green167\\blue0;\
\\red67\\green113\\blue151;\
\\red230\\green66\\blue72;\
\\red90\\green20\\blue132;\
}\\f0\\cf3 ";

static const A_CHAR rtfFooter[] = "}";

A_INT32
string_search(FILE *fp, A_CHAR *string)
{
    A_CHAR str[DBGLOG_DBGID_DEFINITION_LEN_MAX];

    rewind(fp);
    memset(str, 0, DBGLOG_DBGID_DEFINITION_LEN_MAX);
    while (!feof(fp)) {
        if (fgets(str, sizeof(str), fp)) {
            if (strstr(str, string)) return 1;
        }
    }

    return 0;
}

void
get_module_name(A_CHAR *string, A_CHAR *dest)
{
    A_CHAR *str1, *str2;
    A_CHAR str[DBGLOG_DBGID_DEFINITION_LEN_MAX];

    memset(str, 0, DBGLOG_DBGID_DEFINITION_LEN_MAX);
    strcpy(str, string);
    str1 = strtok(str, "_");
    while ((str2 = strtok(NULL, "_"))) {
        str1 = str2;
    }

    strcpy(dest, str1);
}

#ifdef DBGLOG_DEBUG
void
dbglog_print_id_tags(void)
{
    A_INT32 i, j;

    for (i = 0; i < DBGLOG_MODULEID_NUM_MAX; i++) {
        for (j = 0; j < DBGLOG_DBGID_NUM_MAX; j++) {
            printf("[%d][%d]: %s\n", i, j, dbglog_id_tag[i][j]);
        }
    }
}
#endif /* DBGLOG_DEBUG */

A_INT32
dbglog_generate_id_tags(void)
{
    A_INT32 id1, id2;
    FILE *fp1, *fp2;
    A_CHAR str1[DBGLOG_DBGID_DEFINITION_LEN_MAX];
    A_CHAR str2[DBGLOG_DBGID_DEFINITION_LEN_MAX];
    A_CHAR str3[DBGLOG_DBGID_DEFINITION_LEN_MAX];

    if (!(fp1 = fopen(dbglogfile, "r"))) {
        perror(dbglogfile);
        return -1;
    }

    if (!(fp2 = fopen(dbglogidfile, "r"))) {
        fclose(fp1);
        perror(dbglogidfile);
        return -1;
    }

    memset(dbglog_id_tag, 0, sizeof(dbglog_id_tag));
    if (string_search(fp1, "DBGLOG_MODULEID_START")) {
        int ret = fscanf(fp1, "%s %s %d", str1, str2, &id1);
        do {
            memset(str3, 0, DBGLOG_DBGID_DEFINITION_LEN_MAX);
            get_module_name(str2, str3);
            strcat(str3, "_DBGID_DEFINITION_START");
            if (string_search(fp2, str3)) {
                memset(str3, 0, DBGLOG_DBGID_DEFINITION_LEN_MAX);
                get_module_name(str2, str3);
                strcat(str3, "_DBGID_DEFINITION_END");
                ret = fscanf(fp2, "%s %s %d", str1, str2, &id2);
                while (!(strstr(str2, str3))) {
                    strcpy((A_CHAR *)&dbglog_id_tag[id1][id2], str2);
                    ret= fscanf(fp2, "%s %s %d", str1, str2, &id2);
                }
            }
            ret = fscanf(fp1, "%s %s %d", str1, str2, &id1);
        } while (!(strstr(str2, "DBGLOG_MODULEID_END")));
    }

    fclose(fp2);
    fclose(fp1);

    return 0;
}

static void
usage(void)
{
const char options[] = 
"Options:\n\
-d, --srcdir=<Directory containing the dbglog header files> [Optional]\n\
-f, --fileformat 0:plain text, 1:HTML, 2:RTF \n\
-s, --nosystime Don't print out system time\n\
-t, --format 0:Raw, 1:brief, 2:full [0 by default]\n";

    fprintf(stderr, "usage:\n%s [options] <input log file> <output file>\n", progname);
    fprintf(stderr, "%s", options);
    exit(-1);
}

static A_INT32 
decode_debug_rec(struct dbg_binary_record *dbg_rec)
{
#define BUF_SIZE    512
    A_UINT32 count;
    A_UINT32 numargs;
    A_INT32 *buffer;
    A_UINT32 length;
    A_CHAR buf[BUF_SIZE];
    A_UINT32 curpos;
    static A_INT32 numOfRec = 0;
    A_INT32 len;
    char outputBuf[2048];

#ifdef DBGLOG_DEBUG
    RECEVENT_DEBUG_PRINTF("Application received target debug event: %d\n", len);
#endif /* DBGLOG_DEBUG */
    count = 0;
    len = dbg_rec->length;
    length = (len >> 2);
    buffer = (A_INT32 *)dbg_rec->log;

    while (count < length) {
        A_INT32 lret, oret;
        A_UINT32 moduleid = DBGLOG_GET_MODULEID(buffer[count]);
        numargs = DBGLOG_GET_NUMARGS(buffer[count]);
        oret = 0;
        if (outfmt==1) {
            oret += snprintf(outputBuf+oret, sizeof(outputBuf)-oret,
                             "<span class='m%d'>", moduleid);
        } else if (outfmt==2) {
            oret += snprintf(outputBuf+oret, sizeof(outputBuf)-oret,
                             "\\cf%d ", moduleid);
        }
        lret=dbg_formater(fmtlv, outputBuf+oret, sizeof(outputBuf)-oret,
                         noSystime ? 0 : dbg_rec->ts, &buffer[count]);
        if ( lret > 0) {            
#ifdef DBGLOG_DEBUG
            RECEVENT_DEBUG_PRINTF("%s", outputBuf+oret);
#endif /* DBGLOG_DEBUG */

            oret += lret;
            if (outfmt==1) {
                oret += snprintf(outputBuf+oret, sizeof(outputBuf)-oret, "</span><br/>");
            } else if (outfmt==2) {
                oret += snprintf(outputBuf+oret, sizeof(outputBuf)-oret, "\\par");
            }
            fprintf(fpout, "%s", outputBuf);
        }
        count += (numargs + 1);

        numOfRec++;
    }

    /* Update the last rec at the top of file */
    curpos = ftell(fpout);
    if( fgets(buf, BUF_SIZE, fpout) ) {
        buf[BUF_SIZE - 1] = 0;  /* In case string is longer from logs */
        length = strlen(buf);
        memset(buf, ' ', length-1);
        buf[length] = 0;
        fseek(fpout, curpos, SEEK_SET);
        fprintf(fpout, "%s", buf);
    }

    rewind(fpout);
    /* Update last record */
    fseek(fpout, headerlen, SEEK_SET);
    fprintf(fpout, "%08d\n", numOfRec);
    fseek(fpout, curpos, SEEK_SET);
    fflush(fpout);

#undef BUF_SIZE
    return 0;
}

A_INT32 main(A_INT32 argc, A_CHAR** argv)
{
    A_CHAR *workarea = NULL;
    struct dbg_binary_record dbg_rec;
    A_UINT32 min_ts;
    A_INT32 min_rec_num;
    A_UINT32 rec_num;
    A_INT32 i;
    struct dbg_binary_header dbg_header;
    A_UINT16 dbg_rec_len;
    A_UINT16 dbg_header_len;

    progname = argv[0];
    memset(dbgloginfile, 0, FILENAME_LENGTH_MAX);
    memset(dbglogoutfile, 0, FILENAME_LENGTH_MAX);

    while (1) {
        int option_index = 0;
        int c;
        static struct option long_options[] = {
            {"srcdir", 1, NULL, 'd'},
            {"format", 1, NULL, 't'},
            {"fileformat",  1, NULL, 'f'},
            {"nosystime", 0, NULL, 's'},
            {0, 0, 0, 0}
        };
        c = getopt_long (argc, argv, "d:t:f:s", long_options, &option_index);
        if (c == -1) break;

        switch (c) {
            case 'd':
                workarea = optarg;
                break;
            case 't':
                fmtlv = atoi(optarg);
                break;
            case 'f':
                outfmt = atoi(optarg);
                break;
            case 's':
                noSystime = 1;
                break;
            default:
                usage();
        }
    }

    if (!workarea) {
        workarea = getenv("WORKAREA");
    }

    if (workarea == NULL) {
        printf("export WORKAREA or use -d option\n");
        return -1;
    }
    if ((argc - optind)<2) {
        usage();
        return -1;
    }
    /* Get the file name for dbglog header file */
    memset(dbglogfile, 0, FILENAME_LENGTH_MAX);
    strcpy(dbglogfile, workarea);
    strcat(dbglogfile, "/include/");
    strcat(dbglogfile, DBGLOG_FILE);

    /* Get the file name for dbglog id header file */
    memset(dbglogidfile, 0, FILENAME_LENGTH_MAX);
    strcpy(dbglogidfile, workarea);
    strcat(dbglogidfile, "/include/");
    strcat(dbglogidfile, DBGLOGID_FILE);

    /* Get the file name for dbglog input file */
    memset(dbgloginfile, 0, FILENAME_LENGTH_MAX);
    strcpy(dbgloginfile, argv[optind]);
    if (!(fpin = fopen(dbgloginfile, "rb"))) {
        perror(dbgloginfile);
        return -1;
    }

    /* Get the file name for dbglog output file */
    memset(dbglogoutfile, 0, FILENAME_LENGTH_MAX);
    strcpy(dbglogoutfile, argv[optind+1]);
    if (!(fpout = fopen(dbglogoutfile, "w+"))) {
        perror(dbglogoutfile);
        return -1;
    }


    /* first 8 bytes are to indicate the last record */
    switch (outfmt) {
    case 1:
        headerlen = strlen(htmlHeader);
        break;
    case 2:
        headerlen = strlen(rtfHeader);
        break;
    default:
        headerlen = 0;
        break;
    }
    if (outfmt==1) {
        fprintf(fpout, "%s", htmlHeader);
    } else if (outfmt==2) {
        fprintf(fpout, "%s", rtfHeader);
    }
    fseek(fpout, headerlen + 8, SEEK_SET);
    fprintf(fpout, "\n");

    dbglog_generate_id_tags();
#ifdef DBGLOG_DEBUG
    dbglog_print_id_tags();
#endif /* DBGLOG_DEBUG */

    /* first 8 bytes are header */  
    if (fread(&dbg_header, sizeof(struct dbg_binary_header), 1, fpin)!=1) {
        perror("dbg_header mismatch\n");
        return -1;
    }

    /* check header signature */
    dbg_rec_len = sizeof(A_UINT32) * 2;
    if (dbg_header.sig == 0xDB) {
        dbg_rec_len += dbg_header.len;
        dbg_header_len = 8;
    } else {
        /* header not present; assume max size */ 
        dbg_rec_len += AR6K_MAX_DBG_BUFFER_SIZE;
        dbg_header_len = 0;
    }

    /* go past header */
    fseek(fpin, dbg_header_len , SEEK_SET);

    min_ts = 0xFFFFFFFF;
    rec_num = 0;
    min_rec_num = 0;
    while (!feof(fpin)) {
        if (fread (&dbg_rec, dbg_rec_len, 1, fpin)) {
            if (dbg_rec.ts < min_ts) {
                min_ts = dbg_rec.ts;
                min_rec_num = rec_num;
            }
            rec_num++;
        }
    }

    /* go past header */
    fseek(fpin, dbg_header_len , SEEK_SET);

    // Goto the first min record
    fseek(fpin, min_rec_num * dbg_rec_len , SEEK_CUR);
    while (!feof(fpin)) {
        if (fread (&dbg_rec, dbg_rec_len, 1, fpin)) {
            decode_debug_rec(&dbg_rec);
        }
    }

    /* go past header */
    fseek(fpin, dbg_header_len , SEEK_SET);

    for (i=0;i<min_rec_num;i++) {
        if (fread (&dbg_rec, dbg_rec_len, 1, fpin)) {
            decode_debug_rec(&dbg_rec);
        } else {
            break;
        }
    }

    if (outfmt==1) {
        fprintf(fpout, "%s", htmlFooter);
    } else if (outfmt==2) {
        fprintf(fpout, "%s", rtfFooter);
    }

    fclose(fpin);
    fclose(fpout);
    return 0;
}

