#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "coda_string.h"
#include <sys/time.h>
#include <time.h>

#include <odytypes.h>

#include "ds_log.h"
#include "ds_log.private.h"

const magic_t ds_log_magic = 529146149;

static char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

/* Add a time stamp to a log file line */

static void TimeStamp(ds_log_t *lp)
{
    struct timeval tv;
    struct tm *tm;

    gettimeofday(&tv, NULL);
    tm = localtime(&(tv.tv_sec));

    if ((tm->tm_year > lp->oldyear) || (tm->tm_yday > lp->oldday)) {
        fprintf(lp->fp, "\nDate: %3s %02d/%02d/%02d\n\n", days[tm->tm_wday],
                tm->tm_mon + 1, tm->tm_mday, tm->tm_year);
        lp->oldyear = tm->tm_year;
        lp->oldday  = tm->tm_yday;
    }
    fprintf(lp->fp, "%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec);

    if (lp->taglen != 0) {
        fprintf(lp->fp, "[%s] ", lp->tag);
    }
}

bool ds_log_valid(ds_log_t *pl)
{
    if (DS_LOG_VALID(pl)) {
        return TRUE;
    } else {
        return FALSE;
    }
}

ds_log_t *ds_log_create(int level, FILE *fp, int flushlevel, char *name)
{
    ds_log_t *result;

    CODA_ASSERT(fp);
    CODA_ASSERT(name);

    ALLOC(result, ds_log_t);
    result->magic       = ds_log_magic;
    result->fp          = fp;
    result->log_level   = level;
    result->flush_level = flushlevel;
    result->oldyear     = -1;
    result->oldday      = -1;
    result->tag         = name;
    result->taglen      = strlen(name);
    return result;
}

FILE *ds_log_destroy(ds_log_t *pl)
{
    FILE *result;

    CODA_ASSERT(DS_LOG_VALID(pl));
    result = pl->fp;

    pl->magic       = 0;
    pl->fp          = NULL;
    pl->flush_level = pl->oldyear = pl->oldday = 0;
    pl->tag                                    = NULL;

    FREE(pl);
    return result;
}

void ds_log_setlevel(ds_log_t *pl, int level)
{
    CODA_ASSERT(DS_LOG_VALID(pl));
    pl->log_level = level;
}

void ds_log_printmsg(ds_log_t *pl, int level, char *fmt, ...)
{
    va_list ap;

    CODA_ASSERT(DS_LOG_VALID(pl));

    if (level > pl->log_level)
        return;

    TimeStamp(pl);

    va_start(ap, fmt);
    vfprintf(pl->fp, fmt, ap);
    fprintf(pl->fp, "\n");
    va_end(ap);

    if (level >= pl->flush_level)
        fflush(pl->fp);
}
