/*
 * 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.log4j.spi;

import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.Logger;
import org.apache.log4j.plugins.PluginRegistry;
import org.apache.log4j.scheduler.Scheduler;

import java.util.List;
import java.util.Map;


/**
   A <code>LoggerRepository</code> is used to create and retrieve
   <code>Loggers</code>. The relation between loggers in a repository
   depends on the repository but typically loggers are arranged in a
   named hierarchy.

   <p>In addition to the creational methods, a
   <code>LoggerRepository</code> can be queried for existing loggers,
   can act as a point of registry for events related to loggers.

   @author Ceki G&uuml;lc&uuml;
   @author Mark Womack
   @author Curt Arnold
   */
public interface LoggerRepositoryEx extends LoggerRepository {
  /**
    Add a {@link LoggerRepositoryEventListener} to the repository. The
    listener will be called when repository events occur.
     @param listener event listener, may not be null.
    */
  void addLoggerRepositoryEventListener(
    LoggerRepositoryEventListener listener);

  /**
    Remove a {@link LoggerRepositoryEventListener} from the repository.
   @param listener listener.
    */
  void removeLoggerRepositoryEventListener(
    LoggerRepositoryEventListener listener);

  /**
    Add a {@link LoggerEventListener} to the repository. The  listener
    will be called when repository events occur.
   @param listener listener, may not be null.
    */
  void addLoggerEventListener(LoggerEventListener listener);

  /**
    Remove a {@link LoggerEventListener} from the repository.
   @param listener listener, may not be null.
    */
  void removeLoggerEventListener(LoggerEventListener listener);

  /**
   * Get the name of this logger repository.
   * @return name, may not be null.
   */
  String getName();

  /**
   * A logger repository is a named entity.
   * @param repoName new name, may not be null.
   */
  void setName(String repoName);

  /**
   * Is the current configuration of the repository in its original (pristine)
   * state?
   * @return true if repository is in original state.
   *
   */
  boolean isPristine();

  /**
   *  Set the pristine flag.
   * @param state state
   *  @see #isPristine
   */
  void setPristine(boolean state);

  /**
    Requests that a appender removed event be sent to any registered
    {@link LoggerEventListener}.
    @param logger The logger from which the appender was removed.
    @param appender The appender removed from the logger.
    */
  void fireRemoveAppenderEvent(Logger logger, Appender appender);

  /**
    Requests that a level changed event be sent to any registered
    {@link LoggerEventListener}.
    @param logger The logger which changed levels.
    */
  void fireLevelChangedEvent(Logger logger);

  /**
    Requests that a configuration changed event be sent to any registered
    {@link LoggerRepositoryEventListener}.
    */
  void fireConfigurationChangedEvent();

  /**
   * Return the PluginRegistry for this LoggerRepository.
   * @return plug in registry.
   */
  PluginRegistry getPluginRegistry();

  /**
   * Return the {@link Scheduler} for this LoggerRepository.
   * @return scheduler.
   */
  Scheduler getScheduler();

  /**
   * Get the properties specific for this repository.
   * @return property map.
   */
  Map getProperties();

  /**
   * Get the property of this repository.
   * @param key property key.
   * @return key value or null if not set.
   */
  String getProperty(String key);

  /**
   * Set a property of this repository.
   * @param key key, may not be null.
   * @param value new value, if null, property will be removed.
   */
  void setProperty(String key, String value);

  /**
   * Errors which cannot be logged, go to the error list.
   *
   * @return List
   */
  List getErrorList();

  /**
   * Errors which cannot be logged, go to the error list.
   *
   * @param errorItem an ErrorItem to add to the error list
   */
  void addErrorItem(ErrorItem errorItem);

  /**
   * A LoggerRepository can also act as a store for various objects used
   * by log4j components.
   *
   * @param key key, may not be null.
   * @return The object stored under 'key'.
   */
  Object getObject(String key);

  /**
   * Store an object under 'key'. If no object can be found, null is returned.
   *
   * @param key key, may not be null.
   * @param value value, may be null.
   */
  void putObject(String key, Object value);

  /**
   * Sets the logger factory used by LoggerRepository.getLogger(String).
   * @param loggerFactory factory to use, may not be null
   */
  void setLoggerFactory(LoggerFactory loggerFactory);

  /**
   * Returns the logger factory used by
   * LoggerRepository.getLogger(String).
   *
   * @return non-null factory
   */
  LoggerFactory getLoggerFactory();

}
