/*
 * Copyright (c) 1998, 2021 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 final 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.
     *
     * @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("--");
    }
}
