/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2011, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.as.server;

import static org.jboss.logging.Logger.Level.ERROR;
import static org.jboss.logging.Logger.Level.FATAL;
import static org.jboss.logging.Logger.Level.INFO;
import static org.jboss.logging.Logger.Level.WARN;

import java.net.URISyntaxException;
import java.util.jar.Attributes;

import org.jboss.as.controller.PathAddress;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
import org.jboss.as.server.deployment.Phase;
import org.jboss.as.server.deployment.module.ExtensionListEntry;
import org.jboss.as.server.deployment.module.ResourceRoot;
import org.jboss.logging.BasicLogger;
import org.jboss.logging.Logger;
import org.jboss.logging.annotations.Cause;
import org.jboss.logging.annotations.LogMessage;
import org.jboss.logging.annotations.Message;
import org.jboss.logging.annotations.MessageLogger;
import org.jboss.modules.ModuleIdentifier;
import org.jboss.msc.service.ServiceController.Mode;
import org.jboss.vfs.VirtualFile;

/**
 * This module is using message IDs in the range 15700-15999 and 18700-18799.
 * This file is using the subset 15850-15899 and 15950-15999 for server logger messages.
 * See http://community.jboss.org/docs/DOC-16810 for the full list of
 * currently reserved JBAS message id blocks.
 *
 * @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
 * @author Mike M. Clark
 */
@MessageLogger(projectCode = "JBAS")
public interface ServerLogger extends BasicLogger {

    /**
     * A logger with a category of the package name.
     */
    ServerLogger ROOT_LOGGER = Logger.getMessageLogger(ServerLogger.class, ServerLogger.class.getPackage().getName());

    /**
     * A logger with the category {@code org.jboss.as}.
     */
    ServerLogger AS_ROOT_LOGGER = Logger.getMessageLogger(ServerLogger.class, "org.jboss.as");

    /**
     * A logger with the category {@code org.jboss.as.config}.
     */
    ServerLogger CONFIG_LOGGER = Logger.getMessageLogger(ServerLogger.class, "org.jboss.as.config");

    /**
     * A logger with the category {@code org.jboss.as.server.deployment}.
     */
    ServerLogger DEPLOYMENT_LOGGER = Logger.getMessageLogger(ServerLogger.class, "org.jboss.as.server.deployment");

    /**
     * Logger for private APIs.
     */
    ServerLogger PRIVATE_DEP_LOGGER = Logger.getMessageLogger(ServerLogger.class, "org.jboss.as.dependency.private");
    /**
     * Logger for unsupported APIs.
     */
    ServerLogger UNSUPPORTED_DEP_LOGGER = Logger.getMessageLogger(ServerLogger.class, "org.jboss.as.dependency.unsupported");

    /**
     * A logger with the category {@code org.jboss.as.server.moduleservice}.
     */
    ServerLogger MODULE_SERVICE_LOGGER = Logger.getMessageLogger(ServerLogger.class, "org.jboss.as.server.moduleservice");

    /**
     * A logger with the category {@code org.jboss.as.server.net}.
     */
    ServerLogger NETWORK_LOGGER = Logger.getMessageLogger(ServerLogger.class, "org.jboss.as.server.net");

    /**
     * Logger for deprecated APIs.
     */
    ServerLogger DEPRECATED_DEP_LOGGER = Logger.getMessageLogger(ServerLogger.class, "org.jboss.as.dependency.deprecated");

    /**
     * Log message for when a jboss-deployment-structure.xml file is ignored
     * @param file name of the ignored file
     */
    @LogMessage(level = WARN)
    @Message(id = 15850, value = "%s in subdeployment ignored. jboss-deployment-structure.xml is only parsed for top level deployments.")
    void jbossDeploymentStructureIgnored(String file);

    /**
     * Message for when a pre-computed annotation index cannot be loaded
     * @param index name of the annotation index
     */
    @LogMessage(level = ERROR)
    @Message(id = 15851, value = "Could not read provided index: %s")
    void cannotLoadAnnotationIndex(String index);

    @LogMessage(level = WARN)
    @Message(id = 15852, value = "Could not index class %s at %s")
    void cannotIndexClass(String className, String resourceRoot, @Cause Throwable throwable);

    @LogMessage(level = WARN)
    @Message(id = 15853, value = "More than two unique criteria addresses were seen: %s")
    void moreThanTwoUniqueCriteria(String addresses);

    @LogMessage(level = WARN)
    @Message(id = 15854, value = "Checking two unique criteria addresses were seen: %s")
    void checkingTwoUniqueCriteria(String addresses);

    @LogMessage(level = WARN)
    @Message(id = 15855, value = "Two unique criteria addresses were seen: %s")
    void twoUniqueCriteriaAddresses(String addresses);

    @LogMessage(level = ERROR)
    @Message(id = 15856, value = "Undeploy of deployment \"%s\" was rolled back with the following failure message: %s")
    void undeploymentRolledBack(String deployment, String message);

    @LogMessage(level = ERROR)
    @Message(id = 15857, value = "Undeploy of deployment \"%s\" was rolled back with no failure message")
    void undeploymentRolledBackWithNoMessage(String deployment);

    @LogMessage(level = INFO)
    @Message(id = 15858, value = "Undeployed \"%s\" (runtime-name: \"%s\")")
    void deploymentUndeployed(String managementName, String deploymentUnitName);

    @LogMessage(level = INFO)
    @Message(id = 15859, value = "Deployed \"%s\" (runtime-name : \"%s\")")
    void deploymentDeployed(String managementName, String deploymentUnitName);

    @LogMessage(level = ERROR)
    @Message(id = 15860, value = "Redeploy of deployment \"%s\" was rolled back with the following failure message: %s")
    void redeployRolledBack(String deployment, String message);

    @LogMessage(level = ERROR)
    @Message(id = 15861, value = "Redeploy of deployment \"%s\" was rolled back with no failure message")
    void redeployRolledBackWithNoMessage(String deployment);

    @LogMessage(level = INFO)
    @Message(id = 15862, value = "Redeployed \"%s\"")
    void deploymentRedeployed(String deploymentName);

    @LogMessage(level = ERROR)
    @Message(id = 15863, value = "Replacement of deployment \"%s\" by deployment \"%s\" was rolled back with the following failure message: %s")
    void replaceRolledBack(String replaced, String deployment, String message);

    @LogMessage(level = ERROR)
    @Message(id = 15864, value = "Replacement of deployment \"%s\" by deployment \"%s\" was rolled back with no failure message")
    void replaceRolledBackWithNoMessage(String replaced, String deployment);

    @LogMessage(level = INFO)
    @Message(id = 15865, value = "Replaced deployment \"%s\" with deployment \"%s\"")
    void deploymentReplaced(String replaced, String deployment);

    @LogMessage(level = WARN)
    @Message(id = 15866, value = "Annotations import option %s specified in jboss-deployment-structure.xml for additional module %s has been ignored. Additional modules cannot import annotations.")
    void annotationImportIgnored(ModuleIdentifier annotationModuleId, ModuleIdentifier additionalModuleId);

    @LogMessage(level = WARN)
    @Message(id = 15867, value = "Deployment \"%s\" is using a private module (\"%s\") which may be changed or removed in future versions without notice.")
    void privateApiUsed(String deployment, ModuleIdentifier dependency);

    @LogMessage(level = WARN)
    @Message(id = 15868, value = "Deployment \"%s\" is using an unsupported module (\"%s\") which may be changed or removed in future versions without notice.")
    void unsupportedApiUsed(String deployment, ModuleIdentifier dependency);

    @LogMessage(level = WARN)
    @Message(id = 15869, value = "Exception occurred removing deployment content %s")
    void failedToRemoveDeploymentContent(@Cause Throwable cause, String hash);

    @LogMessage(level = ERROR)
    @Message(id = 15870, value = "Deploy of deployment \"%s\" was rolled back with the following failure message: %s")
    void deploymentRolledBack(String deployment, String message);

    @LogMessage(level = ERROR)
    @Message(id = 15871, value = "Deploy of deployment \"%s\" was rolled back with no failure message")
    void deploymentRolledBackWithNoMessage(String deployment);

    @LogMessage(level = WARN)
    @Message(id = 15872, value = "Failed to parse property (%s), value (%s) as an integer")
    void failedToParseCommandLineInteger(String property, String value);

    @LogMessage(level = ERROR)
    @Message(id = 15873, value = "Cannot add module '%s' as URLStreamHandlerFactory provider")
    void cannotAddURLStreamHandlerFactory(@Cause Exception cause, String moduleID);

    @LogMessage(level = INFO)
    @Message(id = 15874, value = "%s started in %dms - Started %d of %d services (%d services are lazy, passive or on-demand)")
    void startedClean(String prettyVersionString, long time, int startedServices, int allServices, int passiveOnDemandServices);

    @LogMessage(level = ERROR)
    @Message(id = 15875, value = "%s started (with errors) in %dms - Started %d of %d services (%d services failed or missing dependencies, %d services are lazy, passive or on-demand)")
    void startedWitErrors(String prettyVersionString, long time, int startedServices, int allServices, int problemServices, int passiveOnDemandServices);

    @LogMessage(level = INFO)
    @Message(id = 15876, value = "Starting deployment of \"%s\" (runtime-name: \"%s\")")
    void startingDeployment(String managementName, String deploymentUnitName);

    @LogMessage(level = INFO)
    @Message(id = 15877, value = "Stopped deployment %s (runtime-name: %s) in %dms")
    void stoppedDeployment(String managementName, String deploymentUnitName, int elapsedTime);

    @LogMessage(level = INFO)
    @Message(id = 15878, value = "Deployment '%s' started successfully")
    void deploymentStarted(String deployment);

    @LogMessage(level = ERROR)
    @Message(id = 15879, value = "Deployment '%s' has failed services%n    Failed services: %s")
    void deploymentHasFailedServices(String deployment, String failures);

    @LogMessage(level = ERROR)
    @Message(id = 15880, value = "Deployment '%s' has services missing dependencies%n    Missing dependencies: %s")
    void deploymentHasMissingDependencies(String deployment, String missing);

    @LogMessage(level = ERROR)
    @Message(id = 15881, value = "Deployment '%s' has failed services and services missing dependencies%n    Failed services: %s%n    Missing dependencies: %s")
    void deploymentHasMissingAndFailedServices(String deployment, String failures, String missing);

    @LogMessage(level = ERROR)
    @Message(id = 15882, value = "%s caught exception attempting to revert operation %s at address %s")
    void caughtExceptionRevertingOperation(@Cause Exception cause, String handler, String operation, PathAddress address);

    @LogMessage(level = WARN)
    @Message(id = 15883, value = "No security realm defined for native management service; all access will be unrestricted.")
    void nativeManagementInterfaceIsUnsecured();

    @LogMessage(level = WARN)
    @Message(id = 15884, value = "No security realm defined for http management service; all access will be unrestricted.")
    void httpManagementInterfaceIsUnsecured();

    @LogMessage(level = INFO)
    @Message(id = 15885, value = "Creating http management service using network interface (%s) and port (%d)")
    void creatingHttpManagementServiceOnPort(String interfaceName, int port);

    @LogMessage(level = INFO)
    @Message(id = 15886, value = "Creating http management service using network interface (%s) and secure port (%d)")
    void creatingHttpManagementServiceOnSecurePort(String interfaceName, int securePort);

    @LogMessage(level = INFO)
    @Message(id = 15887, value = "Creating http management service using network interface (%s), port (%d) and secure port (%d)")
    void creatingHttpManagementServiceOnPortAndSecurePort(String interfaceName, int port, int securePort);

    @LogMessage(level = INFO)
    @Message(id = 15888, value = "Creating http management service using socket-binding (%s)")
    void creatingHttpManagementServiceOnSocket(String socketName);

    @LogMessage(level = INFO)
    @Message(id = 15889, value = "Creating http management service using secure-socket-binding (%s)")
    void creatingHttpManagementServiceOnSecureSocket(String secureSocketName);

    @LogMessage(level = INFO)
    @Message(id = 15890, value = "Creating http management service using socket-binding (%s) and secure-socket-binding (%s)")
    void creatingHttpManagementServiceOnSocketAndSecureSocket(String socketName, String secureSocketName);

    @LogMessage(level = WARN)
    @Message(id = 15891, value = "Caught exception closing input stream for uploaded deployment content")
    void caughtExceptionClosingContentInputStream(@Cause Exception cause);

    @LogMessage(level = ERROR)
    @Message(id = 15892, value = "Deployment unit processor %s unexpectedly threw an exception during undeploy phase %s of %s")
    void caughtExceptionUndeploying(@Cause Throwable cause, DeploymentUnitProcessor dup, Phase phase, DeploymentUnit unit);

    @LogMessage(level = ERROR)
    @Message(id = 15894, value = "Module %s will not have it's annotations processed as no %s file was found in the deployment. Please generate this file using the Jandex ant task.")
    void noCompositeIndex(ModuleIdentifier identifier, String indexLocation);

    @LogMessage(level = WARN)
    @Message(id = 15895, value = "Extension %s is missing the required manifest attribute %s-%s (skipping extension)")
    void extensionMissingManifestAttribute(String item, String again, Attributes.Name suffix);

    @LogMessage(level = WARN)
    @Message(id = 15896, value = "Extension %s URI syntax is invalid: %s")
    void invalidExtensionURI(String item, URISyntaxException e);

    @LogMessage(level = WARN)
    @Message(id = 15897, value = "Could not find Extension-List entry %s referenced from %s")
    void cannotFindExtensionListEntry(ExtensionListEntry entry, ResourceRoot resourceRoot);

    @LogMessage(level = WARN)
    @Message(id = 15898, value = "A server name configuration was provided both via system property %s ('%s') and via the xml configuration ('%s'). The xml configuration value will be used.")
    void duplicateServerNameConfiguration(String systemProperty, String rawServerProp, String processName);

    /**
     * Logs an informational message indicating the server is starting.
     *
     * @param prettyVersion  the server version.
     */
    @LogMessage(level = INFO)
    @Message(id = 15899, value = "%s starting")
    void serverStarting(String prettyVersion);

    /**
     * Logs an informational message indicating the server is stopped.
     *
     * @param prettyVersion  the server version.
     * @param time     the time it took to stop.
     */
    @LogMessage(level = INFO)
    @Message(id = 15950, value = "%s stopped in %dms")
    void serverStopped(String prettyVersion, int time);

    @LogMessage(level = INFO)
    @Message(id = 15951, value= "Admin console listening on http://%s:%d")
    void logHttpConsole(String httpAddr, int httpPort);

    @LogMessage(level = INFO)
    @Message(id = 15952, value= "Admin console listening on https://%s:%d")
    void logHttpsConsole(String httpsAddr, int httpsPort);

    @LogMessage(level = INFO)
    @Message(id = 15953, value= "Admin console listening on http://%s:%d and https://%s:%d")
    void logHttpAndHttpsConsole(String httpAddr, int httpPort, String httpsAddr, int httpsPort);

    @LogMessage(level = INFO)
    @Message(id = 15954, value= "Admin console is not enabled")
    void logNoConsole();

    @LogMessage(level = Logger.Level.ERROR)
    @Message(id = 15956, value = "Caught exception during boot")
    void caughtExceptionDuringBoot(@Cause Exception e);


    @LogMessage(level = Logger.Level.FATAL)
    @Message(id = 15957, value = "Server boot has failed in an unrecoverable manner; exiting. See previous messages for details.")
    void unsuccessfulBoot();

    /**
     * Logs an error message indicating the content for a configured deployment was unavailable at boot but boot
     * was allowed to proceed because the HC is in admin-only mode.
     *
     * @param contentHash    the content hash that could not be found.
     * @param deploymentName the deployment name.
     */
    @LogMessage(level = Logger.Level.ERROR)
    @Message(id = 15958, value = "No deployment content with hash %s is available in the deployment content repository for deployment %s. Because this Host Controller is booting in ADMIN-ONLY mode, boot will be allowed to proceed to provide administrators an opportunity to correct this problem. If this Host Controller were not in ADMIN-ONLY mode this would be a fatal boot failure.")
    void reportAdminOnlyMissingDeploymentContent(String contentHash, String deploymentName);

    @LogMessage(level = Logger.Level.WARN)
    @Message(id = 15959, value = "Additional resource root %s added via jboss-deployment-structure.xml does not exist")
    void additionalResourceRootDoesNotExist(String resourceRoot);

    @LogMessage(level = Logger.Level.WARN)
    @Message(id = 15960, value = "Class Path entry %s in %s  does not point to a valid jar for a Class-Path reference.")
    void classPathEntryNotValid(String classPathEntry, String resourceRoot);

    @LogMessage(level = INFO)
    @Message(id = 15961, value= "Http management interface listening on http://%s:%d/management")
    void logHttpManagement(String httpAddr, int httpPort);

    @LogMessage(level = INFO)
    @Message(id = 15962, value= "Http management interface listening on https://%s:%d/management")
    void logHttpsManagement(String httpsAddr, int httpsPort);

    @LogMessage(level = INFO)
    @Message(id = 15963, value= "Http management interface listening on http://%s:%d/management and https://%s:%d/management")
    void logHttpAndHttpsManagement(String httpAddr, int httpPort, String httpsAddr, int httpsPort);

    @LogMessage(level = INFO)
    @Message(id = 15964, value= "Http management interface is not enabled")
    void logNoHttpManagement();

    @LogMessage(level = WARN)
    @Message(id = 15965, value = "urn:jboss:deployment-structure namespace found in jboss.xml for a sub deployment %s. This is only valid in a top level deployment.")
    void jbossDeploymentStructureNamespaceIgnored(String deploymentUnitName);

    @LogMessage(level = Logger.Level.WARN)
    @Message(id = 15966, value = "Failed to unmount deployment overlay")
    void failedToUnmountContentOverride(@Cause Throwable cause);

    //@LogMessage(level = WARN)
    //@Message(id = 15967, value= "Cannot install reflection index for unresolved bundle: %s")
    //void warnCannotInstallReflectionIndexForUnresolvedBundle(String bundle);

    @LogMessage(level = WARN)
    @Message(id = 15968, value= "jboss-deployment-dependencies cannot be used in a sub deployment, it must be specified at ear level: %s")
    void deploymentDependenciesAreATopLevelElement(String name);

    @LogMessage(level = Logger.Level.ERROR)
    @Message(id = 15969, value = "No deployment overlay content with hash %s is available in the deployment content repository for deployment %s at location %s. Because this Host Controller is booting in ADMIN-ONLY mode, boot will be allowed to proceed to provide administrators an opportunity to correct this problem. If this Host Controller were not in ADMIN-ONLY mode this would be a fatal boot failure.")
    void reportAdminOnlyMissingDeploymentOverlayContent(String contentHash, String deploymentName, String contentName);

    @LogMessage(level = Logger.Level.INFO)
    @Message(id = 15970, value = "Defer %s for %s making it %s")
    void infoDeferDeploymentPhase(Phase phase, String deploymentName, Mode mode);

    @LogMessage(level = Logger.Level.INFO)
    @Message(id = 15971, value = "Deployment restart detected for deployment %s, performing full redeploy instead.")
    void deploymentRestartDetected(String deployment);

    @LogMessage(level = INFO)
    @Message(id = 15973, value = "Starting subdeployment (runtime-name: \"%s\")")
    void startingSubDeployment(String deploymentUnitName);

    @LogMessage(level = INFO)
    @Message(id = 15974, value = "Stopped subdeployment (runtime-name: %s) in %dms")
    void stoppedSubDeployment(String deploymentUnitName, int elapsedTime);

    @LogMessage(level = WARN)
    @Message(id = 15975, value = "Failed to connect to host-controller, retrying.")
    void failedToConnectToHostController();

    @LogMessage(level = ERROR)
    @Message(id = 15976, value = "Error cleaning obsolete content %s ")
    void failedToCleanObsoleteContent(String failure);

    @LogMessage(level = ERROR)
    @Message(id = 15977, value = "Error cleaning obsolete content")
    void failedToCleanObsoleteContent(@Cause Exception e);

    @LogMessage(level = ERROR)
    @Message(id = 15978, value = "Error stopping content repository cleaner")
    void failedToStopRepositoryCleaner(@Cause Exception e);

    @LogMessage(level = WARN)
    @Message(id = 15979, value = "%s deployment has been re-deployed, its content will not be removed. You will need to restart it.")
    void undeployingDeploymentHasBeenRedeployed(String deploymentName);

    @LogMessage(level = WARN)
    @Message(id = 15980, value = "Deployment \"%s\" is using a deprecated module (\"%s\") which may be removed in future versions without notice.")
    void deprecatedApiUsed(String name, ModuleIdentifier id);

    @Message(id = 15981, value = "Unable to initialise a basic SSLContext '%s'")
    IllegalStateException unableToInitialiseSSLContext(String message);

    @LogMessage(level = ERROR)
    @Message(id = 15982, value="Could not mount overlay %s as parent %s is not a directory")
    void couldNotMountOverlay(String path, VirtualFile parent);


    @LogMessage(level = FATAL)
    @Message(id = 15983, value = "Aborting with exit code %d")
    void aborting(int code);

    @LogMessage(level = INFO)
    @Message(id = 15984, value = "ProcessController has signalled to shut down; shutting down")
    void shuttingDownInResponseToProcessControllerSignal();

    @LogMessage(level = INFO)
    @Message(id = 15985, value = "Shutting down in response to management operation '%s'")
    void shuttingDownInResponseToManagementRequest(String op);

    @LogMessage(level = INFO)
    @Message(id = 15986, value = "Host Controller shutdown has been requested via an OS signal")
    void shutdownHookInvoked();
}
