/*
 * 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.logging.log4j.core.jmx;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicLong;

import javax.management.MBeanNotificationInfo;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.ObjectName;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.status.StatusData;
import org.apache.logging.log4j.status.StatusListener;
import org.apache.logging.log4j.status.StatusLogger;

/**
 * Implementation of the {@code StatusLoggerAdminMBean} interface.
 */
public class StatusLoggerAdmin extends NotificationBroadcasterSupport implements StatusListener, StatusLoggerAdminMBean {

    private final AtomicLong sequenceNo = new AtomicLong();
    private final ObjectName objectName;
    private final String contextName;
    private Level level = Level.WARN;

    /**
     * Constructs a new {@code StatusLoggerAdmin} with the {@code Executor} to
     * be used for sending {@code Notification}s asynchronously to listeners.
     * 
     * @param contextName name of the LoggerContext under which to register this
     *            StatusLoggerAdmin. Note that the StatusLogger may be
     *            registered multiple times, once for each LoggerContext. In web
     *            containers, each web application has its own LoggerContext and
     *            by associating the StatusLogger with the LoggerContext, all
     *            associated MBeans can be unloaded when the web application is
     *            undeployed.
     * @param executor used to send notifications asynchronously
     */
    public StatusLoggerAdmin(final String contextName, final Executor executor) {
        super(executor, createNotificationInfo());
        this.contextName = contextName;
        try {
            final String mbeanName = String.format(PATTERN, Server.escape(contextName));
            objectName = new ObjectName(mbeanName);
        } catch (final Exception e) {
            throw new IllegalStateException(e);
        }
        StatusLogger.getLogger().registerListener(this);
    }

    private static MBeanNotificationInfo createNotificationInfo() {
        final String[] notifTypes = new String[] {//
        NOTIF_TYPE_DATA, NOTIF_TYPE_MESSAGE };
        final String name = Notification.class.getName();
        final String description = "StatusLogger has logged an event";
        return new MBeanNotificationInfo(notifTypes, name, description);
    }

    @Override
    public String[] getStatusDataHistory() {
        final List<StatusData> data = getStatusData();
        final String[] result = new String[data.size()];
        for (int i = 0; i < result.length; i++) {
            result[i] = data.get(i).getFormattedStatus();
        }
        return result;
    }

    @Override
    public List<StatusData> getStatusData() {
        return StatusLogger.getLogger().getStatusData();
    }

    @Override
    public String getLevel() {
        return this.level.name();
    }

    @Override
    public void setLevel(final String level) {
        this.level = Level.toLevel(level, Level.ERROR);
    }

    @Override
    public String getContextName() {
        return contextName;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.logging.log4j.status.StatusListener#log(org.apache.logging
     * .log4j.status.StatusData)
     */
    @Override
    public void log(final StatusData data) {
        if (level.isLessSpecificThan(data.getLevel())) {
	    	final Notification notifMsg = new Notification(NOTIF_TYPE_MESSAGE, getObjectName(), nextSeqNo(), now(),
	                data.getFormattedStatus());
	        sendNotification(notifMsg);
	
	        final Notification notifData = new Notification(NOTIF_TYPE_DATA, getObjectName(), nextSeqNo(), now());
	        notifData.setUserData(data);
	        sendNotification(notifData);
        }
    }

    /**
     * Returns the {@code ObjectName} of this mbean.
     * 
     * @return the {@code ObjectName}
     * @see StatusLoggerAdminMBean#PATTERN
     */
    @Override
    public ObjectName getObjectName() {
        return objectName;
    }

    private long nextSeqNo() {
        return sequenceNo.getAndIncrement();
    }

    private long now() {
        return System.currentTimeMillis();
    }

    @Override
    public void close() throws IOException {
        // nothing to close here
    }
}
