/* 
   elmo - ELectronic Mail Operator

   Copyright (C) 2004 rzyjontko

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  

   ----------------------------------------------------------------------

*/
/****************************************************************************
 *    IMPLEMENTATION HEADERS
 ****************************************************************************/

#include <errno.h>

#include "stats.h"
#include "wrapbox.h"
#include "mail.h"
#include "hash.h"
#include "gettext.h"
#include "error.h"

/****************************************************************************
 *    IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES
 ****************************************************************************/

struct estats {
        htable_t *muas;
        htable_t *from;

        int no_mua;
        int no_from;
};

/****************************************************************************
 *    IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID)
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE DATA
 ****************************************************************************/

static FILE *dump_fp  = NULL;
static int   no_field = 0;

/****************************************************************************
 *    INTERFACE DATA
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE FUNCTIONS
 ****************************************************************************/


static void
increment (htable_t *table, char *str)
{
        entry_t *entry = htable_insert (table, str, 0);

        entry->content = (void *) ((int) entry->content + 1);
}


static void
add_mua (struct estats *stats, char *mua)
{
        increment (stats->muas, mua);
}



static void
add_from (struct estats *stats, address_t *addr)
{
        char *name = address_name (addr);

        if (name)
                increment (stats->from, name);
        else
                stats->no_from++;
}


static void
process_mail (struct estats *stats, mail_t *mail)
{
        if (mail->mua)
                add_mua (stats, mail->mua);
        else
                stats->no_mua++;

        if (mail->from)
                add_from (stats, mail->from);
        else
                stats->no_from++;
}


static void
destroy_stats (struct estats *stats)
{
        htable_destroy (stats->muas, NULL);
        htable_destroy (stats->from, NULL);
}



static void
print_key (FILE *fp, char *str)
{
        while (*str){
                if (*str == '\r' || *str == '\n' || *str == '\t')
                        fputc (' ', fp);
                else
                        fputc (*str, fp);
                str++;
        }

        fputc ('\n', fp);
}


static void
dump_stat (entry_t *entry)
{
        float percent;

        percent = ((int) entry->content) /
                (float) (wrapbox_marray->count - no_field);
        
        fprintf (dump_fp, " %d (%.2f%%) - ",
                 (int) entry->content, percent * 100.0);
        print_key (dump_fp, entry->key);
}


static void
dump_stats (struct estats *stats, FILE *fp)
{
        dump_fp = fp;
        
        fprintf (fp, "\nMUA statistics:\n");
        no_field = stats->no_mua;
        htable_iterator (stats->muas, dump_stat);
        fprintf (fp, " %d (%.2f%%) - NULL\n", stats->no_mua,
                 stats->no_mua / (float) wrapbox_marray->count);

        fprintf (fp, "\nFrom statistics:\n");
        no_field = stats->no_from;
        htable_iterator (stats->from, dump_stat);
        fprintf (fp, " %d (%.2f%%) - NULL\n", stats->no_from,
                 stats->no_from / (float) wrapbox_marray->count);

        dump_fp  = NULL;
        no_field = 0;
}

/****************************************************************************
 *    INTERFACE FUNCTIONS
 ****************************************************************************/

void
stats_dump (void)
{
        int            i;
        FILE          *fp;
        mail_t        *mail;
        struct estats  stats;

        if (wrapbox_marray == NULL)
                return;
        
        stats.muas    = htable_create (5);
        stats.from    = htable_create (8);
        stats.no_mua  = 0;
        stats.no_from = 0;

        for (i = 0; i < wrapbox_marray->count; i++){
                mail = mail_array_get (wrapbox_marray, i);
                if (mail != NULL)
                        process_mail (& stats, mail);
        }

        fp = fopen ("/tmp/elmostats", "w");
        if (fp == NULL){
                error_ (errno, _("couldn't open %s"), "/tmp/elmostats");
                destroy_stats (& stats);
                return;
        }

        fprintf (fp, "box path: %s\n", wrapbox_marray->path);
        fprintf (fp, "count: %d\n\n", wrapbox_marray->count);

        dump_stats (& stats, fp);
        destroy_stats (& stats);

        fclose (fp);
}

/****************************************************************************
 *    INTERFACE CLASS BODIES
 ****************************************************************************/
/****************************************************************************
 *
 *    END MODULE stats.c
 *
 ****************************************************************************/


syntax highlighted by Code2HTML, v. 0.9.1