text: /* customTrackTester - test custom tracks functions in library */
  
  /* 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 "obscure.h"
  #include "options.h"
  #include "portable.h"
  #include "hdb.h"
  #include "customFactory.h"
  #include "chromAlias.h"
  
  
  void usage()
  /* explain usage and exit */
  {
  errAbort(
      "customTrackTester - test program for custom tracks library\n\n"
      "usage:\n"
      "    customTrackTester [options] task [args...]\n"
      "         where task/args can be:\n"
      "                   parse inputFile [trashFile]\n"
      "                   check outFile expectedFile\n"
      "options:\n"
      "   -db=<db>  - set database (defaults to %s)\n", hDefaultDb()
      );
  }
  
  static struct optionSpec optionSpecs[] = {
      {"db", OPTION_STRING},
      {NULL, 0}
  };
  
  static void parseCustomTracks(char *db, char *inFile, char *trashFile)
  /* parse tracks from input file, and also from trashfile if not null */
  {
  char *text;
  struct customTrack *ctList = NULL, *oldCts = NULL;
  
  readInGulp(inFile, &text, NULL);
  /* read new CT's from input */
  ctList = customFactoryParse(db, text, FALSE, NULL);
  verbose(3, "parsed %d tracks from %s\n", slCount(ctList), inFile);
  if (trashFile)
      {
      /* read old CT's from trash file */
      oldCts = customFactoryParse(db, trashFile, TRUE, NULL);
      /* merge old and new */
      ctList = customTrackAddToList(ctList, oldCts, NULL, TRUE);
      }
  /* save to new trash file */
  static struct tempName tn;
  makeTempName(&tn, "ctTest", ".bed");
  customTracksSaveFile(db, ctList, tn.forCgi);
  
  /* reload from new trash file */
  ctList = NULL;
  ctList = customFactoryParse(db, tn.forCgi, TRUE, NULL);
  customTracksSaveFile(db, ctList, "stdout");
  
  /* cleanup */
  unlink(tn.forCgi);
  }
  
  static void checkCustomTracks(char *db, char *outFile, char *expectedFile)
  /* compare track lines of output file with expected.  Return error
   * settings are not a proper subset */
  {
  struct hash *expHash = hashNew(0);
  struct customTrack *ct = NULL, *expCt = NULL;
  struct customTrack *newCts = customFactoryParse(db, outFile, TRUE, NULL);
  struct customTrack *expCts = customFactoryParse(db, expectedFile, TRUE, NULL);
  verbose(3, "found %d tracks in output file %s, %d tracks in expected file %s\n",
                  slCount(newCts), outFile, slCount(expCts), expectedFile);
  for (ct = expCts; ct != NULL; ct = ct->next)
      hashAdd(expHash, ct->tdb->track, ct);
  for (ct = newCts; ct != NULL; ct = ct->next)
      {
      if ((expCt = hashFindVal(expHash, ct->tdb->track)) == NULL)
          errAbort("ct %s not found in expected", ct->tdb->track);
      verbose(3, "output settings: %s %s\n%s\n", ct->tdb->track, 
                                  ct->tdb->shortLabel, ct->tdb->settings);
      verbose(3, "expected settings: %s %s\n%s\n", expCt->tdb->track,
                                  expCt->tdb->shortLabel, expCt->tdb->settings);
      struct hash *newSettings = trackDbHashSettings(ct->tdb);
      struct hash *expSettings = trackDbHashSettings(expCt->tdb);
      struct hashCookie hc = hashFirst(expSettings);
      struct hashEl *hel;
      while ((hel = hashNext(&hc)) != NULL)
          {
          char *setting = (char *)hel->name;
          /* ignore DB table name -- it will always differ */
          if (sameString(setting, "dbTableName"))
              continue;
          char *expVal = (char *)hel->val;
          char *newVal = NULL;
          if ((newVal = (char *)hashFindVal(newSettings, setting)) == NULL)
              errAbort("ct %s setting %s not found in new", 
                          ct->tdb->track, setting);
          if (differentString(newVal, expVal))
              errAbort("ct %s setting %s differs from expected: %s should be %s",
                          ct->tdb->track, setting, newVal, expVal);
          }
      }
  }
  
  int main(int argc, char *argv[])
  {
  optionInit(&argc, argv, optionSpecs);
  char *db = optionVal("db", hDefaultDb());
  chromAliasSetup(db);
  if (argc < 2)
      usage();
  char *task = argv[1];
  if (sameString(task, "parse"))
      {
      if (argc < 3)
          usage();
      char *trashFile = NULL;
      char *inFile = argv[2];
      if (argc > 3)
          trashFile = argv[3];
      parseCustomTracks(db, inFile, trashFile);
      }
  else if (sameString(task, "check"))
      {
      if (argc < 4)
          usage();
      char *outFile = argv[2];
      char *expFile = argv[3];
      checkCustomTracks(db, outFile, expFile);
      }
  else
      usage();
  return 0;
  }
  