/*
 * 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.layout.json.template.resolver;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.core.util.JsonUtils;
import org.apache.logging.log4j.layout.json.template.util.JsonWriter;
import org.apache.logging.log4j.message.MapMessage;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MultiformatMessage;
import org.apache.logging.log4j.message.ObjectMessage;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.util.StringBuilderFormattable;

/**
 * {@link Message} resolver.
 *
 * <h3>Configuration</h3>
 *
 * <pre>
 * config      = [ stringified ] , [ fallbackKey ]
 * stringified = "stringified" -> boolean
 * fallbackKey = "fallbackKey" -> string
 * </pre>
 *
 * <h3>Examples</h3>
 *
 * Resolve the message into a string:
 *
 * <pre>
 * {
 *   "$resolver": "message",
 *   "stringified": true
 * }
 * </pre>
 *
 * Resolve the message such that if it is a {@link ObjectMessage} or {@link
 * MultiformatMessage} with JSON support, its emitted JSON type (string, list,
 * object, etc.) will be retained:
 *
 * <pre>
 * {
 *   "$resolver": "message"
 * }
 * </pre>
 *
 * Given the above configuration, a {@link SimpleMessage} will generate a
 * <tt>"sample log message"</tt>, whereas a {@link MapMessage} will generate a
 * <tt>{"action": "login", "sessionId": "87asd97a"}</tt>. Certain indexed log
 * storage systems (e.g., <a
 * href="https://www.elastic.co/elasticsearch/">Elasticsearch</a>) will not
 * allow both values to coexist due to type mismatch: one is a <tt>string</tt>
 * while the other is an <tt>object</tt>. Here one can use a
 * <tt>fallbackKey</tt> to work around the problem:
 *
 * <pre>
 * {
 *   "$resolver": "message",
 *   "fallbackKey": "formattedMessage"
 * }
 * </pre>
 *
 * Using this configuration, a {@link SimpleMessage} will generate a
 * <tt>{"formattedMessage": "sample log message"}</tt> and a {@link MapMessage}
 * will generate a <tt>{"action": "login", "sessionId": "87asd97a"}</tt>. Note
 * that both emitted JSONs are of type <tt>object</tt> and have no
 * type-conflicting fields.
 */
final class MessageResolver implements EventResolver {

    private static final String[] FORMATS = { "JSON" };
    /**
     * Default length for new StringBuilder instances: {@value} .
     */
    protected static final int DEFAULT_STRING_BUILDER_SIZE = 1024;

    private final EventResolver internalResolver;

    private PatternLayout patternLayout;

    MessageResolver(final Configuration configuration, final TemplateResolverConfig config) {
        this.internalResolver = createInternalResolver(configuration, config);
    }

    static String getName() {
        return "message";
    }

    private EventResolver createInternalResolver(final Configuration configuration,
            final TemplateResolverConfig config) {
        final boolean stringified = config.getBoolean("stringified", false);
        final String fallbackKey = config.getString("fallbackKey");
        final String pattern = config.getString("pattern");
        final boolean includeStacktrace = config.getBoolean("includeStacktrace", true);
        if (pattern != null) {
            patternLayout = PatternLayout.newBuilder().setPattern(pattern)
                    .setAlwaysWriteExceptions(includeStacktrace)
                    .setConfiguration(configuration)
                    .build();
        } else {
            patternLayout = null;
        }
        if (stringified && fallbackKey != null) {
            throw new IllegalArgumentException(
                    "fallbackKey is not allowed when stringified is enable: " + config);
        }
        return stringified
                ? createStringResolver(fallbackKey)
                : createObjectResolver(fallbackKey);
    }

    @Override
    public void resolve(
            final LogEvent logEvent,
            final JsonWriter jsonWriter) {
        internalResolver.resolve(logEvent, jsonWriter);
    }

    private EventResolver createStringResolver(final String fallbackKey) {
        return (final LogEvent logEvent, final JsonWriter jsonWriter) ->
                resolveString(fallbackKey, logEvent, jsonWriter);
    }

    private void resolveString(
            final String fallbackKey,
            final LogEvent logEvent,
            final JsonWriter jsonWriter) {
        if (patternLayout != null) {
            final StringBuilder messageBuffer = getMessageStringBuilder();
            patternLayout.serialize(logEvent, messageBuffer);
            jsonWriter.writeString(messageBuffer.toString());
        } else {
            final Message message = logEvent.getMessage();
            resolveString(fallbackKey, message, jsonWriter);
        }
    }

    private void resolveString(
            final String fallbackKey,
            final Message message,
            final JsonWriter jsonWriter) {
        if (fallbackKey != null) {
            jsonWriter.writeObjectStart();
            jsonWriter.writeObjectKey(fallbackKey);
        }
        if (message instanceof StringBuilderFormattable) {
            final StringBuilderFormattable formattable =
                    (StringBuilderFormattable) message;
            jsonWriter.writeString(formattable);
        } else {
            final String formattedMessage = message.getFormattedMessage();
            jsonWriter.writeString(formattedMessage);
        }
        if (fallbackKey != null) {
            jsonWriter.writeObjectEnd();
        }
    }

    private EventResolver createObjectResolver(final String fallbackKey) {
        return (final LogEvent logEvent, final JsonWriter jsonWriter) -> {

            // Skip custom serializers for SimpleMessage.
            final Message message = logEvent.getMessage();
            final boolean simple = message instanceof SimpleMessage;
            if (!simple) {

                // Try MultiformatMessage serializer.
                if (writeMultiformatMessage(jsonWriter, message)) {
                    return;
                }

                // Try ObjectMessage serializer.
                if (writeObjectMessage(jsonWriter, message)) {
                    return;
                }

            }

            // Fallback to plain String serializer.
            resolveString(fallbackKey, logEvent, jsonWriter);

        };
    }

    private boolean writeMultiformatMessage(
            final JsonWriter jsonWriter,
            final Message message) {

        // Check type.
        if (!(message instanceof MultiformatMessage)) {
            return false;
        }
        final MultiformatMessage multiformatMessage = (MultiformatMessage) message;

        // Check formatter's JSON support.
        boolean jsonSupported = false;
        final String[] formats = multiformatMessage.getFormats();
        for (final String format : formats) {
            if (FORMATS[0].equalsIgnoreCase(format)) {
                jsonSupported = true;
                break;
            }
        }
        if (!jsonSupported) {
            return false;
        }

        // Write the formatted JSON.
        final String messageJson = multiformatMessage.getFormattedMessage(FORMATS);
        jsonWriter.writeRawString(messageJson);
        return true;

    }

    private boolean writeObjectMessage(
            final JsonWriter jsonWriter,
            final Message message) {

        // Check type.
        if (!(message instanceof ObjectMessage)) {
            return false;
        }

        // Serialize object.
        final ObjectMessage objectMessage = (ObjectMessage) message;
        final Object object = objectMessage.getParameter();
        jsonWriter.writeValue(object);
        return true;

    }

    private static final ThreadLocal<StringBuilder> messageStringBuilder = new ThreadLocal<>();

    private static StringBuilder getMessageStringBuilder() {
        StringBuilder result = messageStringBuilder.get();
        if (result == null) {
            result = new StringBuilder(DEFAULT_STRING_BUILDER_SIZE);
            messageStringBuilder.set(result);
        }
        result.setLength(0);
        return result;
    }

}
