/******************************************************************************
*
* Copyright (C) 2006-2020  Brian Berlin
* 
* 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, either version 3 of the License, or
* (at your option) any later version.
* 
* 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, see <http://www.gnu.org/licenses/>
*
******************************************************************************
*
* FILENAME: logger.c
*
* DESCRIPTION:  This contains logging functions
*
* AUTHORS:  bberlin
*
* CHANGE LOG
*
*  VER     DATE     CHANGED BY   DESCRIPTION OF CHANGE
* ------  --------  ----------   ------------------------------------
* 0.5.0   01/10/06  bberlin      Creation
* 0.9.0   05/25/20  bberlin      Add printf to console for errors
******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <locale.h>
#ifndef WIN32
#include <langinfo.h>
#endif
#include "../kat5200.h"
#include "logger.h"
#include "util.h"

static FILE *fp = 0;

static char g_tmp_string[1024] = {0};
static char g_logfile[KAT_PATH_MAX] = "kat5200.log";

char * logger_get_string ( e_logger_type type, const char *msg, const char *source );

/******************************************************************************
**  Function   :  logger_init                                            
**                                                                    
**  Objective  :  This function initializes the logging
**                                                   
**  Parameters :  NONE
**                 
**  return     :  0 if success, otherwise failure
** 
******************************************************************************/ 
int logger_init ( void ) {

    char *tmp_string = 0;
    char line[100];

    util_create_program_path ( g_logfile, "kat5200.log" );

    /*
     * Create Initial String and store to buffer
     */
    sprintf ( line, "Starting kat5200 Emulator version %s ...", VERSION );
    tmp_string = logger_get_string ( LOG_INFO, line, "" );

    /* 
     * Open LogFile and write
     */
    fp = fopen ( g_logfile, "w" );

    if ( !fp ) {
        if (tmp_string) free(tmp_string);
        tmp_string = logger_get_string ( LOG_ERROR, "Unable to open log file:", "" );
        fputs ( tmp_string, stderr );
        free ( tmp_string );
        tmp_string = logger_get_string ( LOG_ERROR, g_logfile, "" );
        fputs ( tmp_string, stderr );
        free ( tmp_string );
        return -1;
    }

    fwrite ( tmp_string, sizeof(char), strlen(tmp_string), fp );
    fflush ( fp );

    if (tmp_string)
        free(tmp_string);

    return 0;

} /* end logger_init */

/******************************************************************************
**  Function   :  logger_exit                                            
**                                                                    
**  Objective  :  This function exits the logging
**                                                   
**  Parameters :  NONE
**                 
**  return     :  NONE
******************************************************************************/ 
void logger_exit ( void ) {

    if ( fp )
        fclose ( fp );

} /* end logger_exit */

/******************************************************************************
**  Function   :  logger_log_message
**                                                                    
**  Objective  :  This function appends a message to the log
**                                                   
**  Parameters :  type   - type of message (error,info)
**                msg    - string containing message to display
**                source - where message came from
**                 
**  return     :  NONE
******************************************************************************/ 
void logger_log_message ( e_logger_type type, char *msg, const char *source ) {

    char *tmp_string = 0;

    tmp_string = logger_get_string ( type, msg, source );

    /* Write to file */
    if ( fp ) {
        fwrite ( tmp_string, sizeof(char), strlen(tmp_string), fp );
        fflush ( fp );
    }

    /* Log to console if error */
    if ( type == LOG_ERROR && tmp_string )
        fputs ( tmp_string, stderr );

    if (tmp_string)
        free(tmp_string);

} /* end logger_log_message */

/******************************************************************************
**  Function   :  logger_get_string
**                                                                    
**  Objective  :  This function returns a string with information in it
**                                                   
**  Parameters :  NONE
**                 
**  return     :  message buffer pointer
******************************************************************************/ 
char * logger_get_string ( e_logger_type type, const char *msg, const char *source ) {

    char type_string[257];
    char date_string[257];
    char *time_s;
    char *return_string;
    time_t rawtime;
    struct tm *timeinfo;

    int msg_length = strlen(msg) > 1000 ? 1000 : strlen(msg);
    //    msg[1000] = '\0';

    setlocale (LC_ALL, "");

    /*
     * Get Date and Time
     */
    time ( &rawtime );
    timeinfo = localtime ( &rawtime );

    /*
     * Create Type String
     */
    switch ( type ) {
        case LOG_ERROR: strcpy ( type_string, "E" ); break;
        case LOG_INFO: strcpy ( type_string, "I" ); break;
        default: strcpy ( type_string, "I" ); break;
    }

    /* Bionic only declares nl_langinfo() at API 26+, so Android uses the same
     * fixed format as Windows rather than the locale's D_T_FMT. */
#if defined(WIN32) || defined(__ANDROID__)
    strftime (date_string, sizeof(date_string), "%a %b %e %H:%M:%S %Y", timeinfo);
#else
    strftime (date_string, sizeof(date_string), nl_langinfo (D_T_FMT), timeinfo);
#endif

    //time_s = asctime(timeinfo);
    //time_s[strlen(time_s)-1] = '\0';

    return_string = (char *)malloc ( strlen(type_string) + strlen(date_string) + 
                                     msg_length +strlen(source) + 10 );

    sprintf ( return_string, "%s [%s] %.1000s", type_string, date_string, msg );

    /*
     * Add Source if necessary
     */
    if ( sizeof(source) ) {
        sprintf ( type_string, " [%s]", source );
        strcat ( return_string, source );
    }
    strcat ( return_string, "\n" );

    return return_string;

} /* end logger_get_string */

/******************************************************************************
**  Function   :  logger_get_filename
**                                                                    
**  Objective  :  This function returns the main filename for opening
**                                                   
**  Parameters :  NONE
**                 
**  return     :  filename
******************************************************************************/ 
char * logger_get_filename ( void ) {

    return g_logfile;

} /* end logger_get_filename */
