package org.apache.commons.jcs.log;

/*
 * 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.
 */

import java.text.MessageFormat;
import java.util.Arrays;
import java.util.IllegalFormatException;
import java.util.function.Supplier;

/**
 * Handles messages that consist of a format string conforming to
 * java.text.MessageFormat. (Borrowed from log4j2)
 */
public class MessageFormatter
{
    private String messagePattern;
    private transient Object[] parameters;
    private transient String formattedMessage;
    private transient Throwable throwable;

    /**
     * Constructs a message formatter.
     *
     * @param messagePattern
     *            the pattern for this message format
     * @param parameters
     *            The objects to format
     */
    public MessageFormatter(final String messagePattern, final Object... parameters)
    {
        this.messagePattern = messagePattern;
        this.parameters = parameters;
        final int length = parameters == null ? 0 : parameters.length;
        if (length > 0 && parameters[length - 1] instanceof Throwable)
        {
            this.throwable = (Throwable) parameters[length - 1];
        }
    }

    /**
     * Constructs a message formatter.
     *
     * @param messagePattern
     *            the pattern for this message format
     * @param paramSuppliers
     *            An array of functions, which when called, produce the desired
     *            log message parameters.
     */
    public MessageFormatter(final String messagePattern, final Supplier<?>... paramSuppliers)
    {
        this.messagePattern = messagePattern;
        this.parameters = Arrays.stream(paramSuppliers)
                            .map(s -> s.get())
                            .toArray();

        final int length = parameters == null ? 0 : parameters.length;
        if (length > 0 && parameters[length - 1] instanceof Throwable)
        {
            this.throwable = (Throwable) parameters[length - 1];
        }
    }

    /**
     * Returns the formatted message.
     *
     * @return the formatted message.
     */
    public String getFormattedMessage()
    {
        if (formattedMessage == null)
        {
            formattedMessage = formatMessage(messagePattern, parameters);
        }
        return formattedMessage;
    }

    protected String formatMessage(final String msgPattern, final Object... args)
    {
        try
        {
            final MessageFormat temp = new MessageFormat(msgPattern);
            return temp.format(args);
        }
        catch (final IllegalFormatException ife)
        {
            return msgPattern;
        }
    }

    @Override
    public String toString()
    {
        return getFormattedMessage();
    }

    /**
     * Return the throwable passed to the Message.
     *
     * @return the Throwable.
     */
    public Throwable getThrowable()
    {
        return throwable;
    }

    /**
     * Return true, if the parameters list contains a Throwable.
     *
     * @return true, if the parameters list contains a Throwable.
     */
    public boolean hasThrowable()
    {
        return throwable != null;
    }
}
