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

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.apache.logging.log4j.status.StatusLogger;

/**
 * Provides some level of compatibility with Log4j 1.x and convenience but is not the recommended way to Localize
 * messages.
 * <p>
 * The recommended way to localize messages is to log a message id. Log events should then be recorded without
 * formatting into a data store. The application that is used to read the events and display them to the user can then
 * localize and format the messages for the end user.
 * </p>
 */
public class LocalizedMessage implements Message, LoggerNameAwareMessage {
    private static final long serialVersionUID = 3893703791567290742L;

    private String baseName;

    // ResourceBundle is not Serializable.
    private transient ResourceBundle resourceBundle;

    private final Locale locale;

    private transient StatusLogger logger = StatusLogger.getLogger();

    private String loggerName;
    private String key;
    private String[] stringArgs;
    private transient Object[] argArray;
    private String formattedMessage;
    private transient Throwable throwable;

    /**
     * Constructor with message pattern and arguments.
     *
     * @param messagePattern the message pattern that to be checked for placeholders.
     * @param arguments the argument array to be converted.
     */
    public LocalizedMessage(final String messagePattern, final Object[] arguments) {
        this((ResourceBundle) null, (Locale) null, messagePattern, arguments);
    }

    public LocalizedMessage(final String baseName, final String key, final Object[] arguments) {
        this(baseName, (Locale) null, key, arguments);
    }

    public LocalizedMessage(final ResourceBundle bundle, final String key, final Object[] arguments) {
        this(bundle, (Locale) null, key, arguments);
    }

    public LocalizedMessage(final String baseName, final Locale locale, final String key, final Object[] arguments) {
        this.key = key;
        this.argArray = arguments;
        this.throwable = null;
        this.baseName = baseName;
        this.resourceBundle = null;
        this.locale = locale;
    }

    public LocalizedMessage(final ResourceBundle bundle, final Locale locale, final String key,
            final Object[] arguments) {
        this.key = key;
        this.argArray = arguments;
        this.throwable = null;
        this.baseName = null;
        this.resourceBundle = bundle;
        this.locale = locale;
    }

    public LocalizedMessage(final Locale locale, final String key, final Object[] arguments) {
        this((ResourceBundle) null, locale, key, arguments);
    }

    public LocalizedMessage(final String messagePattern, final Object arg) {
        this((ResourceBundle) null, (Locale) null, messagePattern, new Object[] {arg});
    }

    public LocalizedMessage(final String baseName, final String key, final Object arg) {
        this(baseName, (Locale) null, key, new Object[] {arg});
    }

    /**
     * @param bundle The ResourceBundle for this message.
     * @param key The key of the message in the bundle.
     * @since 2.8
     */
    public LocalizedMessage(final ResourceBundle bundle, final String key) {
        this(bundle, (Locale) null, key, new Object[] {});
    }

    public LocalizedMessage(final ResourceBundle bundle, final String key, final Object arg) {
        this(bundle, (Locale) null, key, new Object[] {arg});
    }

    public LocalizedMessage(final String baseName, final Locale locale, final String key, final Object arg) {
        this(baseName, locale, key, new Object[] {arg});
    }

    public LocalizedMessage(final ResourceBundle bundle, final Locale locale, final String key, final Object arg) {
        this(bundle, locale, key, new Object[] {arg});
    }

    public LocalizedMessage(final Locale locale, final String key, final Object arg) {
        this((ResourceBundle) null, locale, key, new Object[] {arg});
    }

    public LocalizedMessage(final String messagePattern, final Object arg1, final Object arg2) {
        this((ResourceBundle) null, (Locale) null, messagePattern, new Object[] {arg1, arg2});
    }

    public LocalizedMessage(final String baseName, final String key, final Object arg1, final Object arg2) {
        this(baseName, (Locale) null, key, new Object[] {arg1, arg2});
    }

    public LocalizedMessage(final ResourceBundle bundle, final String key, final Object arg1, final Object arg2) {
        this(bundle, (Locale) null, key, new Object[] {arg1, arg2});
    }

    public LocalizedMessage(final String baseName, final Locale locale, final String key, final Object arg1,
            final Object arg2) {
        this(baseName, locale, key, new Object[] {arg1, arg2});
    }

    public LocalizedMessage(final ResourceBundle bundle, final Locale locale, final String key, final Object arg1,
            final Object arg2) {
        this(bundle, locale, key, new Object[] {arg1, arg2});
    }

    public LocalizedMessage(final Locale locale, final String key, final Object arg1, final Object arg2) {
        this((ResourceBundle) null, locale, key, new Object[] {arg1, arg2});
    }

    /**
     * Set the name of the Logger.
     * 
     * @param name The name of the Logger.
     */
    @Override
    public void setLoggerName(final String name) {
        this.loggerName = name;
    }

    /**
     * Returns the name of the Logger.
     * 
     * @return the name of the Logger.
     */
    @Override
    public String getLoggerName() {
        return this.loggerName;
    }

    /**
     * Returns the formatted message after looking up the format in the resource bundle.
     * 
     * @return The formatted message String.
     */
    @Override
    public String getFormattedMessage() {
        if (formattedMessage != null) {
            return formattedMessage;
        }
        ResourceBundle bundle = this.resourceBundle;
        if (bundle == null) {
            if (baseName != null) {
                bundle = getResourceBundle(baseName, locale, false);
            } else {
                bundle = getResourceBundle(loggerName, locale, true);
            }
        }
        final String myKey = getFormat();
        final String msgPattern = (bundle == null || !bundle.containsKey(myKey)) ? myKey : bundle.getString(myKey);
        final Object[] array = argArray == null ? stringArgs : argArray;
        final FormattedMessage msg = new FormattedMessage(msgPattern, array);
        formattedMessage = msg.getFormattedMessage();
        throwable = msg.getThrowable();
        return formattedMessage;
    }

    @Override
    public String getFormat() {
        return key;
    }

    @Override
    public Object[] getParameters() {
        if (argArray != null) {
            return argArray;
        }
        return stringArgs;
    }

    @Override
    public Throwable getThrowable() {
        return throwable;
    }

    /**
     * Override this to use a ResourceBundle.Control in Java 6
     * 
     * @param rbBaseName The base name of the resource bundle, a fully qualified class name.
     * @param resourceBundleLocale The locale to use when formatting the message.
     * @param loop If true the key will be treated as a package or class name and a resource bundle will be located
     *            based on all or part of the package name. If false the key is expected to be the exact bundle id.
     * @return The ResourceBundle.
     */
    protected ResourceBundle getResourceBundle(final String rbBaseName, final Locale resourceBundleLocale,
            final boolean loop) {
        ResourceBundle rb = null;

        if (rbBaseName == null) {
            return null;
        }
        try {
            if (resourceBundleLocale != null) {
                rb = ResourceBundle.getBundle(rbBaseName, resourceBundleLocale);
            } else {
                rb = ResourceBundle.getBundle(rbBaseName);
            }
        } catch (final MissingResourceException ex) {
            if (!loop) {
                logger.debug("Unable to locate ResourceBundle " + rbBaseName);
                return null;
            }
        }

        String substr = rbBaseName;
        int i;
        while (rb == null && (i = substr.lastIndexOf('.')) > 0) {
            substr = substr.substring(0, i);
            try {
                if (resourceBundleLocale != null) {
                    rb = ResourceBundle.getBundle(substr, resourceBundleLocale);
                } else {
                    rb = ResourceBundle.getBundle(substr);
                }
            } catch (final MissingResourceException ex) {
                logger.debug("Unable to locate ResourceBundle " + substr);
            }
        }
        return rb;
    }

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

    private void writeObject(final ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        getFormattedMessage();
        out.writeUTF(formattedMessage);
        out.writeUTF(key);
        out.writeUTF(baseName);
        out.writeInt(argArray.length);
        stringArgs = new String[argArray.length];
        int i = 0;
        for (final Object obj : argArray) {
            stringArgs[i] = obj.toString();
            ++i;
        }
        out.writeObject(stringArgs);
    }

    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        formattedMessage = in.readUTF();
        key = in.readUTF();
        baseName = in.readUTF();
        in.readInt();
        stringArgs = (String[]) in.readObject();
        logger = StatusLogger.getLogger();
        resourceBundle = null;
        argArray = null;
    }
}
