/* sessionDbCrawl - Go through dump of sessionDb table. */

/* Copyright (C) 2011 The Regents of the University of California 
 * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
#include "common.h"
#include "linefile.h"
#include "hash.h"
#include "options.h"


void usage()
/* Explain usage and exit. */
{
errAbort(
  "sessionDbCrawl - Go through dump of sessionDb table\n"
  "usage:\n"
  "   sessionDbCrawl input.tab output\n"
  "options:\n"
  "   -xxx=XXX\n"
  );
}

static struct optionSpec options[] = {
   {NULL, 0},
};

struct trackVar
/* Stats on a track. */
    {
    struct trackVar *next;
    char *name;
    int full;
    int pack;
    int squish;
    int dense;
    int hide;
    };

void addVar(char *name, char *val, struct hash *varHash,
	struct trackVar **pList)
{
int valType = 0;
struct trackVar *tv;
if (sameString(val, "full"))
    valType = 0;
else if (sameString(val, "pack"))
    valType = 1;
else if (sameString(val, "squish"))
    valType = 2;
else if (sameString(val, "dense"))
    valType = 3;
else if (sameString(val, "hide"))
    valType = 4;
else
    return;
tv = hashFindVal(varHash, name);
if (tv == NULL)
    {
    AllocVar(tv);
    // uglyf("Adding %s\n", name);
    hashAddSaveName(varHash, name, tv, &tv->name);
    slAddHead(pList, tv);
    }
switch (valType)
    {
    case 0:
	tv->full += 1;
        break;
    case 1:
	tv->pack += 1;
        break;
    case 2:
	tv->squish += 1;
        break;
    case 3:
	tv->dense += 1;
        break;
    case 4:
	tv->hide += 1;
        break;
    }
}

int anyOn(const struct trackVar *tv)
{
return tv->full + tv->pack + tv->squish + tv->dense;
}

double percentOn(const struct trackVar *tv)
/* Return percentage of time track is on. */
{
long on = anyOn(tv);
long all = on + tv->hide;
return 100.0 * on / all;
}

int trackVarCmp(const void *va, const void *vb)
/* Compare to sort based on percent on . */
{
const struct trackVar *a = *((struct trackVar **)va);
const struct trackVar *b = *((struct trackVar **)vb);
double diff = anyOn(b) - anyOn(a);
if (diff < 0)
    return -1;
else if (diff > 0)
    return 1;
else
    return 0;
}


void parseContents(char *contents, struct hash *varHash, 
	struct trackVar **pList)
/* Parse list of CGI vars.  and add to varHash/list */
{
char *s = contents, *e;

while (s != NULL && s[0] != 0)
    {
    char *name, *val;
    e = strchr(s, '&');
    if (e != 0)
        *e++ = 0;
    name = s;
    val = strchr(s, '=');
    if (val != NULL)
	{
        *val++ = 0;
	if (!startsWith("ct_", name))
	    addVar(name, val, varHash, pList);
	}
    s = e;
    }
    
}

void sessionDbCrawl(char *input, char *output)
/* sessionDbCrawl - Go through dump of sessionDb table. */
{
struct lineFile *lf = lineFileOpen(input, TRUE);
FILE *f = mustOpen(output, "w");
char *row[6];
struct hash *varHash = hashNew(0);
struct trackVar *tvList = NULL, *tv;
while (lineFileRowTab(lf, row))
    {
    char *contents;
    int useCount;
    contents = row[1];
    char *lastUse = row[4];
    useCount = atoi(row[5]);
    if (useCount > 1 && startsWith("2006-10", lastUse) && (stringIn("db=hg18", contents) || stringIn("db=hg17", contents)))
	{
	parseContents(contents, varHash, &tvList);
	}
    }
slSort(&tvList, trackVarCmp);
for (tv = tvList; tv != NULL; tv = tv->next)
    {
    fprintf(f, "%s\t%f\t%d\t%d\t%d\t%d\t%d\n",
    	tv->name, percentOn(tv), tv->full, tv->pack, tv->squish, 
	tv->dense, tv->hide);
    }
carefulClose(&f);
}

int main(int argc, char *argv[])
/* Process command line. */
{
optionInit(&argc, argv, options);
if (argc != 3)
    usage();
sessionDbCrawl(argv[1], argv[2]);
return 0;
}
