/*
 *  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 ${package};

import static org.apache.qpid.server.logging.AbstractMessageLogger.DEFAULT_LOG_HIERARCHY_PREFIX;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.qpid.server.configuration.BrokerProperties;
import org.apache.qpid.server.logging.LogMessage;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 * DO NOT EDIT DIRECTLY, THIS FILE WAS GENERATED.
 *
 * Generated using GenerateLogMessages and LogMessages.vm
 * This file is based on the content of ${type.name}_logmessages.properties
 *
 * To regenerate, edit the templates/properties and run the build with -Dgenerate=true
 */
public class ${type.name}Messages
{
    private static ResourceBundle _messages;
    private static Locale _currentLocale = BrokerProperties.getLocale();

    public static final String ${type.name.toUpperCase()}_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "${type.name.toLowerCase()}";
#foreach( $message in ${type.list} )
    public static final String ${message.methodName.toUpperCase()}_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "${type.name.toLowerCase()}.${message.methodName.toLowerCase()}";
#end

    static
    {
        LoggerFactory.getLogger(${type.name.toUpperCase()}_LOG_HIERARCHY);
#foreach( $message in ${type.list} )
        LoggerFactory.getLogger(${message.methodName.toUpperCase()}_LOG_HIERARCHY);
#end

        _messages = ResourceBundle.getBundle("${resource}", _currentLocale);
    }

##
## The list stored under key 'list' in the 'type' HashMap contains all the
## log messages that this class should contain. So for each entry in the list
## this template will create a new log method.
##
#foreach( $message in ${type.list} )
    /**
     * Log a ${type.name} message of the Format:
     * <pre>${message.format}</pre>
     * Optional values are contained in [square brackets] and are numbered
     * sequentially in the method call.
     *
     */
## There is a lot in the method header here. To make it more readable/understandable
##  This is the same text laid out to be easier to read:
##  public static LogMessage ${message.methodName} (
##          #foreach($parameter in ${message.parameters})
##                ${parameter.type} ${parameter.name}
##                #if (${velocityCount} != ${message.parameters.size()} )
##                   ,
##                #end
##          #end
##          #if(${message.parameters.size()} > 0 && ${message.options.size()} > 0)
##          ,
##          #end
##          #foreach($option in ${message.options})
##          boolean ${option.name}
##          #if (${velocityCount} != ${message.options.size()} )
##             ,
##          #end
##          #end
##         )
##
## What is going on is that we set the method name based on the HashMap lookup
## for 'methodName' Then for each entry(another HashMap) in the list stored
## in the HashMap under 'parameters' build the argument list of from the 'type'
## and 'name' values. Ensuring that we add a ', ' between each entry.
##
## However, check that we are not at the last entry of the list as we don't
## want to add ', ' at then end.
##
## Before we go on to the options we perform a check to see if we had any
## parameters. If we did and we have options to add then we add ', ' to keep
## the syntax correct.
##
## We then go on to the options that are again retrieved from the top HashMap
## with key 'options'. For each option a boolean argument is created and the
## name is retrieved from the option HashMap with key 'name'
##
    public static LogMessage ${message.methodName}(#foreach($parameter in ${message.parameters})${parameter.type} ${parameter.name}#if (${velocityCount} != ${message.parameters.size()} ), #end
#end#if(${message.parameters.size()} > 0 && ${message.options.size()} > 0), #end#foreach($option in ${message.options})boolean ${option.name}#if (${velocityCount} != ${message.options.size()} ), #end#end)
    {
        String rawMessage = _messages.getString("${message.name}");
## If we have some options then we need to build the message based
## on those values so only provide that logic if we need it.
#if(${message.options.size()} > 0)
        StringBuffer msg = new StringBuffer();

        // Split the formatted message up on the option values so we can
        // rebuild the message based on the configured options.
        String[] parts = rawMessage.split("\\[");
        msg.append(parts[0]);

        int end;
        if (parts.length > 1)
        {
## For Each Optional value check if it has been enabled and then
## append it to the log.
#foreach($option in ${message.options})

            // Add Option : ${option.value}.
            end = parts[${velocityCount}].indexOf(']');
            if (${option.name})
            {
                msg.append(parts[${velocityCount}].substring(0, end));
            }

            // Use 'end + 1' to remove the ']' from the output
            msg.append(parts[${velocityCount}].substring(end + 1));
#end
        }

        rawMessage = msg.toString();
#end

##
## If we don't have any parameters then we don't need the overhead of using the
## message formatter so we can just set our return message to the retreived
## fixed string. So we don't need to create a new MessageFormat
##
## Here we setup rawMessage to be the formatted message ready for direct return
## with the message.name or further processing to remove options.
##
#if(${message.parameters.size()} > 0)
        final Object[] messageArguments = {#foreach($parameter in ${message.parameters})${parameter.name}#if (${velocityCount} != ${message.parameters.size()} ), #end#end};
        // Create a new MessageFormat to ensure thread safety.
        // Sharing a MessageFormat and using applyPattern is not thread safe
        MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);

        final String message = formatter.format(messageArguments);
#else
## If we have no parameters then we can skip the formating and set the log
        final String message = rawMessage;
#end

        return new LogMessage()
        {
            public String toString()
            {
                return message;
            }

            public String getLogHierarchy()
            {
                return ${message.methodName.toUpperCase()}_LOG_HIERARCHY;
            }

            @Override
            public boolean equals(final Object o)
            {
                if (this == o)
                {
                    return true;
                }
                if (o == null || getClass() != o.getClass())
                {
                    return false;
                }

                final LogMessage that = (LogMessage) o;

                return getLogHierarchy().equals(that.getLogHierarchy()) && toString().equals(that.toString());

            }

            @Override
            public int hashCode()
            {
                int result = toString().hashCode();
                result = 31 * result + getLogHierarchy().hashCode();
                return result;
            }
        };
    }

#end

    private ${type.name}Messages()
    {
    }

}
