/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.felix.eventadmin.impl.util;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;

/**
 * This class mimics the standard OSGi <tt>LogService</tt> interface. An
 * instance of this class will be used by the EventAdmin for all logging. The
 * implementation of this class sends log messages to standard output, if no
 * <tt>LogService</tt> is present; it uses a log service if one is
 * installed in the framework. To do that without creating a hard dependency on the
 * package it uses fully qualified class names and registers a listener with the
 * framework hence, it does not need access to the <tt>LogService</tt> class but will
 * use it if the listener is informed about an available service. By using a
 * DynamicImport-Package dependency we don't need the package but
 * use it if present. Additionally, all log methods prefix the log message with
 * <tt>EventAdmin: </tt>.
 *
 * There is one difference in behavior from the standard OSGi LogService.
 * This logger has a {@link #m_logLevel} property which decides what messages
 * get logged.
 *
 * @see org.osgi.service.log.LogService
 *
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
**/
// TODO: At the moment we log a message to all currently available LogServices.
//       Maybe, we should only log to the one with the highest ranking instead?
//       What is the best practice in this case?
public class LogWrapper
{
    /**
     * ERROR LEVEL
     *
     * @see org.osgi.service.log.LogService#LOG_ERROR
     */
    public static final int LOG_ERROR = 1;

    /**
     * WARNING LEVEL
     *
     * @see org.osgi.service.log.LogService#LOG_WARNING
     */
    public static final int LOG_WARNING = 2;

    /**
     * INFO LEVEL
     *
     * @see org.osgi.service.log.LogService#LOG_INFO
     */
    public static final int LOG_INFO = 3;

    /**
     * DEBUG LEVEL
     *
     * @see org.osgi.service.log.LogService#LOG_DEBUG
     */
    public static final int LOG_DEBUG = 4;

    // A set containing the currently available LogServices. Furthermore used as lock
    private final Set<ServiceReference<?>> m_loggerRefs = new HashSet<>();

    // Only null while not set and m_loggerRefs is empty hence, only needs to be
    // checked in case m_loggerRefs is empty otherwise it will not be null.
    private BundleContext m_context;

    private ServiceListener m_logServiceListener;

    /**
     * Current log level. Message with log level less than or equal to
     * current log level will be logged.
     * The default value is {@link #LOG_WARNING}
     *
     * @see #setLogLevel(int)
     */
    private int m_logLevel = LOG_WARNING;
    /*
     * A thread save variant of the double checked locking singleton.
     */
    private static class LogWrapperLoader
    {
        static final LogWrapper m_singleton = new LogWrapper();
    }

    /**
     * Returns the singleton instance of this LogWrapper that can be used to send
     * log messages to all currently available LogServices or to standard output,
     * respectively.
     *
     * @return the singleton instance of this LogWrapper.
     */
    public static LogWrapper getLogger()
    {
        return LogWrapperLoader.m_singleton;
    }

    /**
     * Set the <tt>BundleContext</tt> of the bundle. This method registers a service
     * listener for LogServices with the framework that are subsequently used to
     * log messages.
     * <p>
     * If the bundle context is <code>null</code>, the service listener is
     * unregistered and all remaining references to LogServices dropped before
     * internally clearing the bundle context field.
     *
     *  @param context The context of the bundle.
     */
    public static void setContext( final BundleContext context )
    {
        LogWrapper logWrapper = LogWrapperLoader.m_singleton;

        // context is removed, unregister and drop references
        if ( context == null )
        {
            if ( logWrapper.m_logServiceListener != null )
            {
                logWrapper.m_context.removeServiceListener( logWrapper.m_logServiceListener );
                logWrapper.m_logServiceListener = null;
            }
            logWrapper.removeLoggerRefs();
        }

        // set field
        logWrapper.setBundleContext( context );

        // context is set, register and get existing services
        if ( context != null )
        {
            try
            {
                ServiceListener listener = new ServiceListener()
                {
                    // Add a newly available LogService reference to the singleton.
                    @Override
                    public void serviceChanged( final ServiceEvent event )
                    {
                        if ( ServiceEvent.REGISTERED == event.getType() )
                        {
                            LogWrapperLoader.m_singleton.addLoggerRef( event.getServiceReference() );
                        }
                        // unregistered services are handled in the next log operation.
                    }

                };
                context.addServiceListener( listener, "(" + Constants.OBJECTCLASS + "=org.osgi.service.log.LogService)" );
                logWrapper.m_logServiceListener = listener;

                // Add all available LogService references to the singleton.
                final ServiceReference<?>[] refs = context.getServiceReferences( "org.osgi.service.log.LogService", null );

                if ( null != refs )
                {
                    for ( int i = 0; i < refs.length; i++ )
                    {
                        logWrapper.addLoggerRef( refs[i] );
                    }
                }
            }
            catch ( InvalidSyntaxException e )
            {
                // this never happens
            }
        }
    }


    /*
     * The private singleton constructor.
     */
    LogWrapper()
    {
        // Singleton
    }

    /*
     * Removes all references to LogServices still kept
     */
    void removeLoggerRefs()
    {
        synchronized ( m_loggerRefs )
        {
            m_loggerRefs.clear();
        }
    }

    /*
     * Add a reference to a newly available LogService
     */
    void addLoggerRef( final ServiceReference<?> ref )
    {
        synchronized (m_loggerRefs)
        {
            m_loggerRefs.add(ref);
        }
    }

    /*
     * Set the context of the bundle in the singleton implementation.
     */
    private void setBundleContext(final BundleContext context)
    {
        synchronized(m_loggerRefs)
        {
            m_context = context;
        }
    }

    /**
     * Log a message with the given log level. Note that this will prefix the message
     * with <tt>EventAdmin: </tt>.
     *
     * @param level The log level with which to log the msg.
     * @param msg The message to log.
     */
    public void log(final int level, final String msg)
    {
        // The method will remove any unregistered service reference as well.
        synchronized(m_loggerRefs)
        {
            if (level > m_logLevel)
            {
                return; // don't log
            }

            final String logMsg = "EventAdmin: " + msg;

            if (!m_loggerRefs.isEmpty())
            {
                // There is at least one LogService available hence, we can use the
                // class as well.
                for (Iterator<ServiceReference<?>> iter = m_loggerRefs.iterator(); iter.hasNext();)
                {
                    final ServiceReference<?> next = iter.next();

                    org.osgi.service.log.LogService logger =
                        (org.osgi.service.log.LogService) m_context.getService(next);

                    if (null != logger)
                    {
                        logger.log(level, logMsg);

                        m_context.ungetService(next);
                    }
                    else
                    {
                        // The context returned null for the reference - it follows
                        // that the service is unregistered and we can remove it
                        iter.remove();
                    }
                }
            }
            else
            {
                _log(null, level, logMsg, null);
            }
        }
    }

    /**
     * Log a message with the given log level and the associated exception. Note that
     * this will prefix the message with <tt>EventAdmin: </tt>.
     *
     * @param level The log level with which to log the msg.
     * @param msg The message to log.
     * @param ex The exception associated with the message.
     */
    public void log(final int level, final String msg, final Throwable ex)
    {
        // The method will remove any unregistered service reference as well.
        synchronized(m_loggerRefs)
        {
            if (level > m_logLevel)
            {
                return; // don't log
            }

            final String logMsg = "EventAdmin: " + msg;

            if (!m_loggerRefs.isEmpty())
            {
                // There is at least one LogService available hence, we can use the
                // class as well.
                for (Iterator<ServiceReference<?>> iter = m_loggerRefs.iterator(); iter.hasNext();)
                {
                    final ServiceReference<?> next = iter.next();

                    org.osgi.service.log.LogService logger =
                        (org.osgi.service.log.LogService) m_context.getService(next);

                    if (null != logger)
                    {
                        logger.log(level, logMsg, ex);

                        m_context.ungetService(next);
                    }
                    else
                    {
                        // The context returned null for the reference - it follows
                        // that the service is unregistered and we can remove it
                        iter.remove();
                    }
                }
            }
            else
            {
                _log(null, level, logMsg, ex);
            }
        }
    }

    /**
     * Log a message with the given log level together with the associated service
     * reference. Note that this will prefix the message with <tt>EventAdmin: </tt>.
     *
     * @param sr The reference of the service associated with this message.
     * @param level The log level with which to log the msg.
     * @param msg The message to log.
     */
    public void log(final ServiceReference<?> sr, final int level, final String msg)
    {
        // The method will remove any unregistered service reference as well.
        synchronized(m_loggerRefs)
        {
            if (level > m_logLevel)
            {
                return; // don't log
            }

            final String logMsg = "EventAdmin: " + msg;

            if (!m_loggerRefs.isEmpty())
            {
                // There is at least one LogService available hence, we can use the
                // class as well.
                for (Iterator<ServiceReference<?>> iter = m_loggerRefs.iterator(); iter.hasNext();)
                {
                    final ServiceReference<?> next = iter.next();

                    org.osgi.service.log.LogService logger =
                        (org.osgi.service.log.LogService) m_context.getService(next);

                    if (null != logger)
                    {
                        logger.log(sr, level, logMsg);

                        m_context.ungetService(next);
                    }
                    else
                    {
                        // The context returned null for the reference - it follows
                        // that the service is unregistered and we can remove it
                        iter.remove();
                    }
                }
            }
            else
            {
                _log(sr, level, logMsg, null);
            }
        }
    }

    /**
     * Log a message with the given log level, the associated service reference and
     * exception. Note that this will prefix the message with <tt>EventAdmin: </tt>.
     *
     * @param sr The reference of the service associated with this message.
     * @param level The log level with which to log the msg.
     * @param msg The message to log.
     * @param ex The exception associated with the message.
     */
    public void log(final ServiceReference<?> sr, final int level, final String msg,
        final Throwable ex)
    {
        // The method will remove any unregistered service reference as well.
        synchronized(m_loggerRefs)
        {
            if (level > m_logLevel)
            {
                return; // don't log
            }

            final String logMsg = "EventAdmin: " + msg;

            if (!m_loggerRefs.isEmpty())
            {
                // There is at least one LogService available hence, we can use the
                // class as well.
                for (Iterator<ServiceReference<?>> iter = m_loggerRefs.iterator(); iter.hasNext();)
                {
                       final ServiceReference<?> next = iter.next();

                    org.osgi.service.log.LogService logger =
                        (org.osgi.service.log.LogService) m_context.getService(next);

                    if (null != logger)
                    {
                        logger.log(sr, level, logMsg, ex);

                        m_context.ungetService(next);
                    }
                    else
                    {
                        // The context returned null for the reference - it follows
                        // that the service is unregistered and we can remove it
                        iter.remove();
                    }
                }
            }
            else
            {
                _log(sr, level, logMsg, ex);
            }
        }
    }

    /*
     * Log the message to standard output. This appends the level to the message.
     * null values are handled appropriate.
     */
    private void _log(final ServiceReference<?> sr, final int level, final String msg,
        Throwable ex)
    {
        String s = (sr == null) ? null : "SvcRef " + sr;
        s = (s == null) ? msg : s + " " + msg;
        s = (ex == null) ? s : s + " (" + ex + ")";

        switch (level)
        {
            case LOG_DEBUG:
                System.out.println("DEBUG: " + s);
                break;
            case LOG_ERROR:
                System.out.println("ERROR: " + s);
                if (ex != null)
                {
                    if ((ex instanceof BundleException)
                        && (((BundleException) ex).getNestedException() != null))
                    {
                        ex = ((BundleException) ex).getNestedException();
                    }

                    ex.printStackTrace();
                }
                break;
            case LOG_INFO:
                System.out.println("INFO: " + s);
                break;
            case LOG_WARNING:
                System.out.println("WARNING: " + s);
                break;
            default:
                System.out.println("UNKNOWN[" + level + "]: " + s);
        }
    }

    /**
     * Change the current log level. Log level decides what messages gets
     * logged. Any message with a log level higher than the currently set
     * log level is not logged.
     *
     * @param logLevel new log level
     */
    public void setLogLevel(int logLevel)
    {
        synchronized (m_loggerRefs)
        {
            m_logLevel = logLevel;
        }
    }

    /**
     * @return current log level.
     */
    public int getLogLevel()
    {
        synchronized (m_loggerRefs)
        {
            return m_logLevel;
        }
    }
}
