/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.logging;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.helper.Helper;

/**
 * <b>Purpose</b>: Default log used for the session when message logging is
 * enabled. The session can log information such as,
 * <ul>
 * <li>all SQL executed
 * <li>informational messages
 * <li>debugging information
 * <li>all exceptions that occur within TopLink
 * </ul>
 * As well information about the message can be logged such as,
 * <ul>
 * <li>the session logging the message
 * <li>the connection executing the SQL
 * <li>the thread in which the log entry occurred
 * <li>the exact time (to milliseconds) that the log entry occurred
 * <li>the stack trace to the exception
 * </ul>
 *
 * @see SessionLog
 * @see AbstractSessionLog
 *
 * @author Big Country
 */
public class DefaultSessionLog extends AbstractSessionLog implements Serializable {

    /**
     * The filename associated with this DefaultSessionLog, if it is being
     * written out to a file
     **/
    protected String fileName;

    /**
     * Represents the Map that stores log levels per the name space strings. The
     * keys are category names. The values are log levels.
     */
    private Map<String, Integer> categoryLogLevelMap = new HashMap();

    public DefaultSessionLog() {
        super();
        for (int i = 0; i < loggerCatagories.length; i++) {
            String loggerCategory = loggerCatagories[i];
            categoryLogLevelMap.put(loggerCategory, null);
        }
    }

    public DefaultSessionLog(Writer writer) {
        this();
        this.initialize(writer);
    }

    @Override
    public void setLevel(int level, String category) {
        if (category == null) {
            this.level = level;
        } else if (categoryLogLevelMap.containsKey(category)) {
            categoryLogLevelMap.put(category, level);
        }
    }

    @Override
    public int getLevel(String category) {
        if (category != null) {
            Integer level = this.categoryLogLevelMap.get(category);

            if (level != null) {
                return level;
            }
        }

        return super.getLevel(category);
    }

    /**
     * Check if a message of the given level would actually be logged by the
     * logger with name space built from the given session and category.
     * <p>
     *
     * @return true if the given message level will be logged for the given
     *         category
     */
    @Override
    public boolean shouldLog(int level, String category) {
        return (getLevel(category) <= level);
    }

    /**
     * Initialize the log to be backward-compatible with the original TopLink
     * log.
     */
    protected void initialize() {
        this.setShouldPrintSession(true);
        this.setShouldPrintConnection(true);
    }

    /**
     * Initialize the log.
     */
    protected void initialize(Writer writer) {
        this.writer = writer;
    }

    /**
     * Log the entry. This writes the log entries information to a
     * writer such as System.out or a file.
     */
    @Override
    public void log(SessionLogEntry entry) {
        if (!shouldLog(entry.getLevel(), entry.getNameSpace())) {
            return;
        }

        synchronized (this) {
            try {
                printPrefixString(entry.getLevel(), entry.getNameSpace());
                this.getWriter().write(getSupplementDetailString(entry));

                if (entry.hasMessage()) {
                    writeMessage(formatMessage(entry));
                    getWriter().write(Helper.cr());
                    getWriter().flush();
                }

                if (entry.hasException()) {
                    if (shouldLogExceptionStackTrace()) {
                        entry.getException().printStackTrace(new PrintWriter(getWriter()));
                    } else {
                        writeMessage(entry.getException().toString());
                    }
                    getWriter().write(Helper.cr());
                    getWriter().flush();
                }
            } catch (IOException exception) {
                throw ValidationException.logIOError(exception);
            }
        }
    }

    /**
     * Set the writer that will receive the formatted log entries for a
     * file name.
     */
    public void setWriter(String aFileName) {
        if (aFileName != null) {
            try {
                this.writer = new FileWriter(aFileName);
                this.fileName = aFileName;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * For the given writer, return it's associated filename. If
     * associated writer does not have a filename, return null.
     */
    public String getWriterFilename() {
        return fileName;
    }

    /**
     * Append the specified message information to the writer.
     */
    protected void writeMessage(String message) throws IOException {
        this.getWriter().write(message);
    }

    /**
     * Append the separator string to the writer.
     */
    protected void writeSeparator() throws IOException {
        this.getWriter().write("--");
    }
}
