/** 
 * Display what the underlying tidbits think the config is
 * 
 * @param trackerp grab the configuration info from the portscan tracker
 */
static void FlowPSOutputConfig(PS_TRACKER *trackerp)
{
    if(pv.quiet_flag)
        return;

    flow_printf(",-----------[flow-portscan config]-------------\n");
    flow_printf("| TCP Penalties:  %s\n", trackerp->config.tcp_penalties ? "On": "Off");
    flow_printf("|    Ouput Mode:  %s\n",
                (trackerp->config.output_mode == VARIABLEMSG) ? "msg" : "pktkludge");
    flow_printf("|    Base Score:  %d\n", trackerp->config.base_score);
    
    flow_printf("+----------------------------------------------\n");
    flow_printf("| Scoreboard:  ACTIVE         PORTSCANNER\n");
    flow_printf("|     memcap:  %-8d         %-8d\n",
                scoreboard_memcap(&trackerp->table_active),
                scoreboard_memcap(&trackerp->table_scanner));
    flow_printf("|       rows:  %-8d         %-8d\n",
                scoreboard_row_count(&trackerp->table_active),
                scoreboard_row_count(&trackerp->table_scanner));
    flow_printf("|   overhead:  %-8d(%%%.02lf) %-8d(%%%.02lf)\n",
                scoreboard_overhead_bytes(&trackerp->table_active),
                calc_percent(scoreboard_overhead_bytes(&trackerp->table_active),
                             scoreboard_memcap(&trackerp->table_active)),
                scoreboard_overhead_bytes(&trackerp->table_scanner),
                calc_percent(scoreboard_overhead_bytes(&trackerp->table_scanner),
                             scoreboard_memcap(&trackerp->table_scanner)));

    flow_printf("|      fixed-size:    %-4ds        %-4ds\n",
                trackerp->config.limit_talker.fixed_size,
                trackerp->config.limit_scanner.fixed_size);
    flow_printf("|    sliding-size:    %-4ds        %-4ds\n",
                trackerp->config.limit_talker.sliding_size,
                trackerp->config.limit_scanner.sliding_size);
    flow_printf("| threshold-fixed:    %-4u         %-4u\n",
                trackerp->config.limit_talker.fixed,
                trackerp->config.limit_scanner.fixed);
    flow_printf("| threshold-sliding:  %-4u         %-4u\n",
                trackerp->config.limit_talker.sliding,
                trackerp->config.limit_scanner.sliding);
    flow_printf("|      window scale:  %-.2lf         %-.2lf\n",
                trackerp->config.limit_talker.window_scale,
                trackerp->config.limit_scanner.window_scale);
    
    
    flow_printf("+----------------------------------------------\n");
    flow_printf("|   Uniqueness:  memcap: %8d rows: %8d\n",
               ut_memcap(&trackerp->unique_tracker),
               ut_row_count(&trackerp->unique_tracker));
    flow_printf("|      overhead: %d (%%%.02lf)\n",               
                ut_overhead_bytes(&trackerp->unique_tracker),
                calc_percent(ut_overhead_bytes(&trackerp->unique_tracker),
                             ut_memcap(&trackerp->unique_tracker)));
    
    if(flowps_server_stats_enabled(trackerp) == FLOW_SUCCESS)
    {
        flow_printf("+----------------------------------------------\n");        
        flow_printf("| Server Stats:  memcap: %8d rows: %8d\n",
                    server_stats_memcap(&trackerp->server_stats),
                    server_stats_row_count(&trackerp->server_stats));
        flow_printf("|      overhead: %d (%%%.02lf)\n",               
                    server_stats_overhead_bytes(&trackerp->server_stats),
                    calc_percent(server_stats_overhead_bytes(&trackerp->server_stats),
                                 server_stats_memcap(&trackerp->server_stats)));
        flow_printf("|   learning time: %d\n",
                    trackerp->config.server_learning_time);
        flow_printf("|    ignore limit: %u\n",
                    trackerp->config.server_ignore_limit);
        flow_printf("|   scanner limit: %u\n",
                    trackerp->config.server_scanner_limit);
        
        
    }
    else
    {
        flow_printf("| Server Stats: Disabled\n");
    }

    flow_printf("`----------------------------------------------\n");
}
/** 
 * initialize the Portscan Tracker.
 *
 * This takes several arguments, all, on the PS_CONFIG structure.
 * 
 * @param trackerp tracker object to initialize
 * @param configp well-formed configuration to initialize this object
 * 
 * @return FLOW_SUCCESS on success
 */
int flowps_init(PS_TRACKER *trackerp, PS_CONFIG *configp)
{
    int ret;
    
    if(!trackerp || !configp)
        return FLOW_ENULL;

    /* we should validate this threshold object somewhat */
    memcpy(&trackerp->config, configp, sizeof(PS_CONFIG));    

    ret = scoreboard_init(&trackerp->table_active,            /* table */
                          "Active Talkers",                   /* description */
                          TRACKER_ACTIVE,                     /* position */
                          trackerp->config.sb_rows_talker,    /* node count */
                          trackerp->config.sb_memcap_talker); /* memcap */

    if(ret != FLOW_SUCCESS)
    {
        return ret;
    }
    
    ret = scoreboard_init(&trackerp->table_scanner,            /* table */
                          "Portscanners",                      /* description */
                          TRACKER_SCANNER,                     /* position */
                          trackerp->config.sb_rows_scanner,    /* node count */
                          trackerp->config.sb_memcap_scanner); /* memcap */

    if(ret != FLOW_SUCCESS)
    {
        scoreboard_destroy(&trackerp->table_active);
        return ret;
    }

    /* setup the unique talkers table */
    ret = ut_init(&trackerp->unique_tracker,trackerp->config.ut_rows, trackerp->config.ut_memcap);

    if(ret != FLOW_SUCCESS)
    {
        scoreboard_destroy(&trackerp->table_active);
        scoreboard_destroy(&trackerp->table_scanner);
        return ret;
    }

    /* the watchnet stuff is optional */
    if(flowps_server_stats_enabled(trackerp) == FLOW_SUCCESS)
    {
        ret = server_stats_init(&trackerp->server_stats,
                                trackerp->config.server_watchnet_ipv4,
                                trackerp->config.server_rows,
                                trackerp->config.server_memcap);

        if(ret != FLOW_SUCCESS)
        {
            scoreboard_destroy(&trackerp->table_active);
            scoreboard_destroy(&trackerp->table_scanner);
            ut_destroy(&trackerp->unique_tracker);
            return ret;
        }
    }    

    s_enabled = 1;
    
    return FLOW_SUCCESS;
}