/*
 * 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.config.status;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.status.StatusListener;
import org.apache.logging.log4j.status.StatusLogger;

/**
 * Configuration for setting up {@link StatusConsoleListener} instances.
 */
public class StatusConfiguration {

    private static final Level DEFAULT_STATUS = Level.ERROR;
    private static final Verbosity DEFAULT_VERBOSITY = Verbosity.QUIET;

    private final Collection<String> errorMessages = Collections.synchronizedCollection(new LinkedList<String>());
    private final StatusLogger logger = StatusLogger.getLogger();

    private volatile boolean initialized = false;

    private Class<? extends StatusConsoleListener> destination = StatusStdOutListener.class;
    private Level status = DEFAULT_STATUS;
    private Verbosity verbosity = DEFAULT_VERBOSITY;
    private String[] verboseClasses;

    /**
     * Specifies how verbose the StatusLogger should be.
     */
    public static enum Verbosity {
        QUIET, VERBOSE;

        /**
         * Parses the verbosity property into an enum.
         *
         * @param value property value to parse.
         * @return enum corresponding to value, or QUIET by default.
         */
        public static Verbosity toVerbosity(final String value) {
            return Boolean.parseBoolean(value) ? VERBOSE : QUIET;
        }
    }

    /**
     * Logs an error message to the StatusLogger. If the StatusLogger hasn't been set up yet, queues the message to be
     * logged after initialization.
     *
     * @param message error message to log.
     */
    public void error(final String message) {
        if (!this.initialized) {
            this.errorMessages.add(message);
        } else {
            this.logger.error(message);
        }
    }

    /**
     * Specifies the destination for StatusLogger events. This can be {@code out} (default) for using
     * {@link System#out standard out}, {@code err} for using {@link System#err standard error}, or a file URI to
     * which log events will be written. If the provided URI is invalid, then the default destination of standard
     * out will be used.
     *
     * @param destination where status log messages should be output.
     * @return {@code this}
     */
    public StatusConfiguration withDestination(final String destination) {
    	if ("out".equalsIgnoreCase(destination)) {
    		this.destination = StatusStdOutListener.class;
    	} else if ("err".equalsIgnoreCase(destination)) {
    		this.destination = StatusStdErrListener.class;
    	} else {
    		this.error("Invalid destination [" + destination + "]. Only 'out' or 'err' are supported. Defaulting to 'out'.");
    		this.destination = StatusStdOutListener.class;
    	}
        return this;
    }

    /**
     * Specifies the logging level by name to use for filtering StatusLogger messages.
     *
     * @param status name of logger level to filter below.
     * @return {@code this}
     * @see Level
     */
    public StatusConfiguration withStatus(final String status) {
        this.status = Level.toLevel(status, null);
        if (this.status == null) {
            this.error("Invalid status level specified: " + status + ". Defaulting to ERROR.");
            this.status = Level.ERROR;
        }
        return this;
    }

    /**
     * Specifies the logging level to use for filtering StatusLogger messages.
     *
     * @param status logger level to filter below.
     * @return {@code this}
     */
    public StatusConfiguration withStatus(final Level status) {
        this.status = status;
        return this;
    }

    /**
     * Specifies the verbosity level to log at. This only applies to classes configured by
     * {@link #withVerboseClasses(String...) verboseClasses}.
     *
     * @param verbosity basic filter for status logger messages.
     * @return {@code this}
     */
    public StatusConfiguration withVerbosity(final String verbosity) {
        this.verbosity = Verbosity.toVerbosity(verbosity);
        return this;
    }

    /**
     * Specifies which class names to filter if the configured verbosity level is QUIET.
     *
     * @param verboseClasses names of classes to filter if not using VERBOSE.
     * @return {@code this}
     */
    public StatusConfiguration withVerboseClasses(final String... verboseClasses) {
        this.verboseClasses = verboseClasses;
        return this;
    }

    /**
     * Configures and initializes the StatusLogger using the configured options in this instance.
     */
    public void initialize() {
        if (!this.initialized) {
            if (this.status == Level.OFF) {
                this.initialized = true;
            } else {
                final boolean configured = configureExistingStatusConsoleListener();
                if (!configured) {
                    registerNewStatusConsoleListener();
                }
                migrateSavedLogMessages();
            }
        }
    }

    private boolean configureExistingStatusConsoleListener() {
        boolean configured = false;
        for (final StatusListener statusListener : this.logger.getListeners()) {
        	if (this.destination.isInstance(statusListener)) {
                final StatusConsoleListener listener = (StatusConsoleListener) statusListener;
                listener.setStatusLevel(this.status);
                if (this.verbosity == Verbosity.QUIET) {
                    listener.setFilters(this.verboseClasses);
                }
                configured = true;
            }
        }
        return configured;
    }


    private void registerNewStatusConsoleListener() {
        StatusConsoleListener listener;
		try {
			listener = this.destination.newInstance();
	        listener.setStatusLevel(this.status);
	        if (this.verbosity == Verbosity.QUIET) {
	            listener.setFilters(this.verboseClasses);
	        }
	        this.logger.registerListener(listener);
		} catch (ReflectiveOperationException e) {
			logger.error("Cannot create listener of type " + destination.getClass());
		}
    }

    private void migrateSavedLogMessages() {
        for (final String message : this.errorMessages) {
            this.logger.error(message);
        }
        this.initialized = true;
        this.errorMessages.clear();
    }
}