/*
 * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * This source code is provided to illustrate the usage of a given feature
 * or technique and has been deliberately simplified. Additional steps
 * required for a production-quality application, such as security checks,
 * input validation and proper error handling, might not be present in
 * this sample code.
 */


package com.sun.jmx.examples.scandir;

import static com.sun.jmx.examples.scandir.ScanManager.getNextSeqNumber;
import com.sun.jmx.examples.scandir.config.ResultLogConfig;
import com.sun.jmx.examples.scandir.config.XmlConfigUtils;
import com.sun.jmx.examples.scandir.config.ResultRecord;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.ObjectName;
import javax.xml.bind.JAXBException;

/**
 * The <code>ResultLogManager</code> is in charge of managing result logs.
 * {@link DirectoryScanner DirectoryScanners} can be configured to log a
 * {@link ResultRecord} whenever they take action upon a file that
 * matches their set of matching criteria.
 * The <code>ResultLogManagerMXBean</code> is responsible for storing these
 * results in its result logs.
 * <p>The <code>ResultLogManagerMXBean</code> can be configured to log
 * these records to a flat file, or into a log held in memory, or both.
 * Both logs (file and memory) can be configured with a maximum capacity.
 * <br>When the maximum capacity of the memory log is reached - its first
 * entry (i.e. its eldest entry) is removed to make place for the latest.
 * <br>When the maximum capacity of the file log is reached, the file is
 * renamed by appending a tilde '~' to its name and a new result log is created.
 *
 *
 * @author Sun Microsystems, 2006 - All rights reserved.
 */
public class ResultLogManager extends NotificationBroadcasterSupport
        implements ResultLogManagerMXBean, MBeanRegistration {

    /**
     * The default singleton name of the {@link ResultLogManagerMXBean}.
     **/
    public static final ObjectName RESULT_LOG_MANAGER_NAME =
            ScanManager.makeSingletonName(ResultLogManagerMXBean.class);

    /**
     * A logger for this class.
     **/
    private static final Logger LOG =
            Logger.getLogger(ResultLogManager.class.getName());

    // The memory log
    //
    private final List<ResultRecord> memoryLog;

    // Whether the memory log capacity was reached. In that case every
    // new entry triggers the deletion of the eldest one.
    //
    private volatile boolean memCapacityReached = false;

    // The maximum number of record that the memory log can
    // contain.
    //
    private volatile int memCapacity;

    // The maximum number of record that the ResultLogManager can
    // log in the log file before creating a new file.
    //
    private volatile long fileCapacity;

    // The current log file.
    //
    private volatile File logFile;

    // The OutputStream of the current log file.
    //
    private volatile OutputStream logStream = null;

    // number of record that this object has logged in the log file
    // since the log file was created. Creating a new file or clearing
    // the log file reset this value to '0'
    //
    private volatile long logCount = 0;

    // The ResultLogManager config - modified whenever
    // ScanManager.applyConfiguration is called.
    //
    private volatile ResultLogConfig config;

    /**
     * Create a new ResultLogManagerMXBean. This constructor is package
     * protected: only the {@link ScanManager} can create a
     * <code>ResultLogManager</code>.
     **/
    ResultLogManager() {
        // Instantiate the memory log - override the add() method so that
        // it removes the head of the list when the maximum capacity is
        // reached. Note that add() is the only method we will be calling,
        // otherwise we would have to override all the other flavors
        // of adding methods. Note also that this implies that the memoryLog
        // will *always* remain encapsulated in this object and is *never*
        // handed over (otherwise we wouldn't be able to ensure that
        // add() is the only method ever called to add a record).
        //
        memoryLog =
                Collections.synchronizedList(new LinkedList<ResultRecord>() {
            public synchronized boolean add(ResultRecord e) {
                final int max = getMemoryLogCapacity();
                while (max > 0 && size() >= max) {
                    memCapacityReached = true;
                    removeFirst();
                }
                return super.add(e);
            }
        });

        // default memory capacity
        memCapacity = 2048;

        // default file capacity: 0 means infinite ;-)
        fileCapacity = 0;

        // by default logging to file is disabled.
        logFile = null;

        // Until the ScanManager apply a new configuration, we're going to
        // work with a default ResultLogConfig object.
        config = new ResultLogConfig();
        config.setMemoryMaxRecords(memCapacity);
        config.setLogFileName(getLogFileName(false));
        config.setLogFileMaxRecords(fileCapacity);
    }


    /**
     * Allows the MBean to perform any operations it needs before being
     * registered in the MBean server.
     * <p>If the name of the MBean is not
     * specified, the MBean can provide a name for its registration. If
     * any exception is raised, the MBean will not be registered in the
     * MBean server.</p>
     * <p>The {@code ResultLogManager} uses this method to supply its own
     * default singleton ObjectName (if <var>name</var> parameter is null).
     * @param server The MBean server in which the MBean will be registered.
     * @param name The object name of the MBean. This name is null if the
     * name parameter to one of the createMBean or registerMBean methods in
     * the MBeanServer interface is null. In that case, this method must
     * return a non-null ObjectName for the new MBean.
     * @return The name under which the MBean is to be registered. This value
     * must not be null. If the name parameter is not null, it will usually
     * but not necessarily be the returned value.
     * @throws Exception This exception will be caught by the MBean server and
     * re-thrown as an MBeanRegistrationException.
     */
    public ObjectName preRegister(MBeanServer server, ObjectName name)
    throws Exception {
        if (name == null)
            name = RESULT_LOG_MANAGER_NAME;
        objectName = name;
        mbeanServer = server;
        return name;
    }

    /**
     * Allows the MBean to perform any operations needed after having
     * been registered in the MBean server or after the registration has
     * failed.
     * <p>This implementation does nothing.</p>
     * @param registrationDone Indicates whether or not the MBean has been
     * successfully registered in the MBean server. The value false means
     * that the registration has failed.
     */
    public void postRegister(Boolean registrationDone) {
        // Don't need to do anything here.
    }

    /**
     * Allows the MBean to perform any operations it needs before being
     * unregistered by the MBean server.
     * <p>This implementation does nothing.</p>
     * @throws Exception This exception will be caught by the MBean server and
     * re-thrown as an MBeanRegistrationException.
     */
    public void preDeregister() throws Exception {
        // Don't need to do anything here.
    }

    /**
     * Allows the MBean to perform any operations needed after having been
     * unregistered in the MBean server.
     * <p>Closes the log file stream, if it is still open.</p>
     */
    public void postDeregister() {
        try {
            if (logStream != null) {
                synchronized(this)  {
                    logStream.flush();
                    logStream.close();
                    logFile = null;
                    logStream = null;
                }
            }
        } catch (Exception x) {
            LOG.finest("Failed to close log properly: "+x);
        }
    }

    /**
     * Create a new empty log file from the given basename, renaming
     * previously existing file by appending '~' to its name.
     **/
    private File createNewLogFile(String basename) throws IOException {
        return XmlConfigUtils.createNewXmlFile(basename);
    }

    /**
     * Check whether a new log file should be created.
     * If a new file needs to be created, creates it, renaming
     * previously existing file by appending '~' to its name.
     * Also reset the log count and file capacity.
     * Sends a notification indicating that the log file was changed.
     * Returns the new log stream;
     * Creation of a new file can be forced by passing force=true.
     **/
    private OutputStream checkLogFile(String basename, long maxRecords,
                                      boolean force)
    throws IOException {
        final OutputStream newStream;
        synchronized(this) {
            if ((force==false) && (logCount < maxRecords))
                return logStream;
            final OutputStream oldStream = logStream;

            // First close the stream. On some platforms you cannot rename
            // a file that has open streams...
            //
            if (oldStream != null) {
                oldStream.flush();
                oldStream.close();
            }
            final File newFile = (basename==null)?null:createNewLogFile(basename);

            newStream = (newFile==null)?null:new FileOutputStream(newFile,true);
            logStream = newStream;
            logFile = newFile;
            fileCapacity = maxRecords;
            logCount = 0;
        }
        sendNotification(new Notification(LOG_FILE_CHANGED,objectName,
                getNextSeqNumber(),
                basename));
        return newStream;
    }

    // see ResultLogManagerMXBean
    public void log(ResultRecord record)
    throws IOException {
        if (memCapacity > 0) logToMemory(record);
        if (logFile != null) logToFile(record);
    }

    // see ResultLogManagerMXBean
    public ResultRecord[] getMemoryLog() {
        return memoryLog.toArray(new ResultRecord[0]);
    }

    // see ResultLogManagerMXBean
    public int getMemoryLogCapacity() {
        return memCapacity;
    }

    // see ResultLogManagerMXBean
    public void setMemoryLogCapacity(int maxRecords)  {
        synchronized(this) {
            memCapacity = maxRecords;
            if (memoryLog.size() < memCapacity)
                memCapacityReached = false;
            config.setMemoryMaxRecords(maxRecords);
        }
    }

    // see ResultLogManagerMXBean
    public void setLogFileCapacity(long maxRecords)
    throws IOException {
        synchronized (this) {
            fileCapacity = maxRecords;
            config.setLogFileMaxRecords(maxRecords);
        }
        checkLogFile(getLogFileName(),fileCapacity,false);
    }

    // see ResultLogManagerMXBean
    public long getLogFileCapacity()  {
        return fileCapacity;
    }

    // see ResultLogManagerMXBean
    public long getLoggedCount() {
        return logCount;
    }

    // see ResultLogManagerMXBean
    public void newLogFile(String logname, long maxRecord)
    throws IOException {
        checkLogFile(logname,maxRecord,true);
        config.setLogFileName(getLogFileName(false));
        config.setLogFileMaxRecords(getLogFileCapacity());
    }

    // see ResultLogManagerMXBean
    public String getLogFileName() {
        return getLogFileName(true);
    }

    // see ResultLogManagerMXBean
    public void clearLogs() throws IOException {
        clearMemoryLog();
        clearLogFile();
    }

    // Clear the memory log, sends a notification indicating that
    // the memory log was cleared.
    //
    private void clearMemoryLog()throws IOException {
        synchronized(this) {
            memoryLog.clear();
            memCapacityReached = false;
        }
        sendNotification(new Notification(MEMORY_LOG_CLEARED,
                objectName,
                getNextSeqNumber(),"memory log cleared"));
    }

    // Clears the log file.
    //
    private void clearLogFile() throws IOException {
        // simply force the creation of a new log file.
        checkLogFile(getLogFileName(),fileCapacity,true);
    }

    // Log a record to the memory log. Send a notification if the
    // maximum capacity of the memory log is reached.
    //
    private void logToMemory(ResultRecord record) {

        final boolean before = memCapacityReached;
        final boolean after;
        synchronized(this) {
            memoryLog.add(record);
            after = memCapacityReached;
        }
        if (before==false && after==true)
            sendNotification(new Notification(MEMORY_LOG_MAX_CAPACITY,
                    objectName,
                    getNextSeqNumber(),"memory log capacity reached"));
    }


    // Log a record to the memory log. Send a notification if the
    // maximum capacity of the memory log is reached.
    //
    private void logToFile(ResultRecord record) throws IOException {
        final String basename;
        final long   maxRecords;
        synchronized (this) {
            if (logFile == null) return;
            basename = getLogFileName(false);
            maxRecords = fileCapacity;
        }

        // Get the stream into which we should log.
        final OutputStream stream =
                checkLogFile(basename,maxRecords,false);

        // logging to file now disabled - too bad.
        if (stream == null) return;

        synchronized (this) {
            try {
                XmlConfigUtils.write(record,stream,true);
                stream.flush();
                // don't increment logCount if we were not logging in logStream.
                if (stream == logStream) logCount++;
            } catch (JAXBException x) {
                final IllegalArgumentException iae =
                        new IllegalArgumentException("bad record",x);
                LOG.finest("Failed to log record: "+x);
                throw iae;
            }
        }
    }

    /**
     * The notification type which indicates that the log file was switched:
     * <i>com.sun.jmx.examples.scandir.log.file.switched</i>.
     * The message contains the name of the new file (or null if log to file
     * is now disabled).
     **/
    public final static String LOG_FILE_CHANGED =
            "com.sun.jmx.examples.scandir.log.file.switched";

    /**
     * The notification type which indicates that the memory log capacity has
     * been reached:
     * <i>com.sun.jmx.examples.scandir.log.memory.full</i>.
     **/
    public final static String MEMORY_LOG_MAX_CAPACITY =
            "com.sun.jmx.examples.scandir.log.memory.full";

    /**
     * The notification type which indicates that the memory log was
     * cleared:
     * <i>com.sun.jmx.examples.scandir.log.memory.cleared</i>.
     **/
    public final static String MEMORY_LOG_CLEARED =
            "com.sun.jmx.examples.scandir.log.memory.cleared";

    /**
     * This MBean emits three kind of notifications:
     * <pre>
     *    <i>com.sun.jmx.examples.scandir.log.file.switched</i>
     *    <i>com.sun.jmx.examples.scandir.log.memory.full</i>
     *    <i>com.sun.jmx.examples.scandir.log.memory.cleared</i>
     * </pre>
     **/
    public MBeanNotificationInfo[] getNotificationInfo() {
        return new MBeanNotificationInfo[] {
            new MBeanNotificationInfo(new String[] {
                LOG_FILE_CHANGED},
                    Notification.class.getName(),
                    "Emitted when the log file is switched")
                    ,
            new MBeanNotificationInfo(new String[] {
                MEMORY_LOG_MAX_CAPACITY},
                    Notification.class.getName(),
                    "Emitted when the memory log capacity is reached")
                    ,
            new MBeanNotificationInfo(new String[] {
                MEMORY_LOG_CLEARED},
                    Notification.class.getName(),
                    "Emitted when the memory log is cleared")
        };
    }

    // Return the name of the log file, or null if logging to file is
    // disabled.
    private String getLogFileName(boolean absolute) {
        synchronized (this) {
            if (logFile == null) return null;
            if (absolute) return logFile.getAbsolutePath();
            return logFile.getPath();
        }
    }

    // This method is be called by the ScanManagerMXBean when a configuration
    // is applied.
    //
    void setConfig(ResultLogConfig logConfigBean) throws IOException {
        if (logConfigBean == null)
            throw new IllegalArgumentException("logConfigBean is null");
        synchronized (this) {
            config = logConfigBean;
            setMemoryLogCapacity(config.getMemoryMaxRecords());
        }
        final String filename = config.getLogFileName();
        final String logname  = getLogFileName(false);
        if ((filename != null && !filename.equals(logname))
        || (filename == null && logname != null)) {
            newLogFile(config.getLogFileName(),
                    config.getLogFileMaxRecords());
        } else {
            setLogFileCapacity(config.getLogFileMaxRecords());
        }
    }

    // This method is called by the ScanManagerMXBean when
    // applyCurrentResultLogConfig() is called.
    //
    ResultLogConfig getConfig() {
        return config;
    }


    // Set by preRegister().
    private MBeanServer mbeanServer;
    private ObjectName objectName;



}
