/*
 * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "util.h"

#include <time.h>
#include <errno.h>
#include <sys/types.h>

#include "proc_md.h"

#include "log_messages.h"

#ifdef JDWP_LOGGING

#define MAXLEN_INTEGER          20
#define MAXLEN_FILENAME         256
#define MAXLEN_TIMESTAMP        80
#define MAXLEN_LOCATION         (MAXLEN_FILENAME+MAXLEN_INTEGER+16)
#define MAXLEN_MESSAGE          256
#define MAXLEN_EXEC             (MAXLEN_FILENAME*2+MAXLEN_INTEGER+16)

static MUTEX_T my_mutex = MUTEX_INIT;

/* Static variables (should be protected with mutex) */
static int logging;
static FILE * log_file;
static char logging_filename[MAXLEN_FILENAME+1+6];
static char location_stamp[MAXLEN_LOCATION+1];
static PID_T processPid;
static int open_count;

/* Ascii id of current native thread. */
static void
get_time_stamp(char *tbuf, size_t ltbuf)
{
    char format[MAXLEN_TIMESTAMP+1];
    unsigned millisecs = 0;
    time_t t = 0;

    GETMILLSECS(millisecs);
    if ( time(&t) == (time_t)(-1) )
        t = 0;
    (void)strftime(format, sizeof(format),
                /* Break this string up for SCCS's sake */
                "%" "d.%" "m.%" "Y %" "T.%%.3d %" "Z", localtime(&t));
    (void)snprintf(tbuf, ltbuf, format, (int)(millisecs));
}

/* Get basename of filename */
static const char *
file_basename(const char *file)
{
    char *p1;
    char *p2;

    if ( file==NULL )
        return "unknown";
    p1 = strrchr(file, '\\');
    p2 = strrchr(file, '/');
    p1 = ((p1 > p2) ? p1 : p2);
    if (p1 != NULL) {
        file = p1 + 1;
    }
    return file;
}

/* Fill in the exact source location of the LOG entry. */
static void
fill_location_stamp(const char *flavor, const char *file, int line)
{
    (void)snprintf(location_stamp, sizeof(location_stamp),
                    "%s:\"%s\":%d;",
                    flavor, file_basename(file), line);
    location_stamp[sizeof(location_stamp)-1] = 0;
}

/* Begin a log entry. */
void
log_message_begin(const char *flavor, const char *file, int line)
{
    MUTEX_LOCK(my_mutex); /* Unlocked in log_message_end() */
    if ( logging ) {
        location_stamp[0] = 0;
        fill_location_stamp(flavor, file, line);
    }
}

/* Standard Logging Format Entry */
static void
standard_logging_format(FILE *fp,
        const char *datetime,
        const char *level,
        const char *product,
        const char *module,
        const char *optional,
        const char *messageID,
        const char *message)
{
    const char *format;

    /* "[#|Date&Time&Zone|LogLevel|ProductName|ModuleID|
     *     OptionalKey1=Value1;OptionalKeyN=ValueN|MessageID:MessageText|#]\n"
     */

    format="[#|%s|%s|%s|%s|%s|%s:%s|#]\n";

    print_message(fp, "", "", format,
            datetime,
            level,
            product,
            module,
            optional,
            messageID,
            message);
}

/* End a log entry */
void
log_message_end(const char *format, ...)
{
    if ( logging ) {
        va_list ap;
        THREAD_T tid;
        char datetime[MAXLEN_TIMESTAMP+1];
        const char *level;
        const char *product;
        const char *module;
        char optional[MAXLEN_INTEGER+6+MAXLEN_INTEGER+6+MAXLEN_LOCATION+1];
        const char *messageID;
        char message[MAXLEN_MESSAGE+1];

        /* Grab the location, start file if needed, and clear the lock */
        if ( log_file == NULL && open_count == 0 && logging_filename[0] != 0 ) {
            open_count++;
            log_file = fopen(logging_filename, "w");
            if ( log_file!=NULL ) {
                (void)setvbuf(log_file, NULL, _IOLBF, BUFSIZ);
            } else {
                logging = 0;
            }
        }

        if ( log_file != NULL ) {

            /* Get the rest of the needed information */
            tid = GET_THREAD_ID();
            level = "FINEST"; /* FIXUP? */
            product = "J2SE1.5"; /* FIXUP? */
            module = "jdwp"; /* FIXUP? */
            messageID = ""; /* FIXUP: Unique message string ID? */
            (void)snprintf(optional, sizeof(optional),
                        "LOC=%s;PID=%d;THR=t@%d",
                        location_stamp,
                        (int)processPid,
                        (int)tid);

            /* Construct message string. */
            va_start(ap, format);
            (void)vsnprintf(message, sizeof(message), format, ap);
            va_end(ap);

            get_time_stamp(datetime, sizeof(datetime));

            /* Send out standard logging format message */
            standard_logging_format(log_file,
                datetime,
                level,
                product,
                module,
                optional,
                messageID,
                message);
        }
        location_stamp[0] = 0;
    }
    MUTEX_UNLOCK(my_mutex); /* Locked in log_message_begin() */
}

#endif

/* Set up the logging with the name of a logging file. */
void
setup_logging(const char *filename, unsigned flags)
{
#ifdef JDWP_LOGGING
    FILE *fp = NULL;

    /* Turn off logging */
    logging = 0;
    gdata->log_flags = 0;

    /* Just return if not doing logging */
    if ( filename==NULL || flags==0 )
        return;

    /* Create potential filename for logging */
    processPid = GETPID();
    (void)snprintf(logging_filename, sizeof(logging_filename),
                    "%s.%d", filename, (int)processPid);

    /* Turn on logging (do this last) */
    logging = 1;
    gdata->log_flags = flags;

#endif
}

/* Finish up logging, flush output to the logfile. */
void
finish_logging(int exit_code)
{
#ifdef JDWP_LOGGING
    MUTEX_LOCK(my_mutex);
    if ( logging ) {
        logging = 0;
        if ( log_file != NULL ) {
            (void)fflush(log_file);
            (void)fclose(log_file);
            log_file = NULL;
        }
    }
    MUTEX_UNLOCK(my_mutex);
#endif
}
