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

import java.util.logging.LogManager;
import java.util.logging.LogRecord;

/**
 * Provides the same information as the one line format but using JSON formatting. All the information of the LogRecord
 * is included as a one line JSON document, including the full stack trace of the associated exception if any.
 * <p>
 * The LogRecord is mapped as attributes:
 * <ul>
 * <li>time: the log record timestamp, with the default format as {@code yyyy-MM-dd'T'HH:mm:ss.SSSX}</li>
 * <li>level: the log level</li>
 * <li>thread: the current on which the log occurred</li>
 * <li>class: the class from which the log originated</li>
 * <li>method: the method from which the log originated</li>
 * <li>message: the log message</li>
 * <li>throwable: the full stack trace from an exception, if present, represented as an array of string (the message
 * first, then one string per stack trace element prefixed by a whitespace, then moving on to the cause exception if
 * any)</li>
 * </ul>
 */
public class JsonFormatter extends OneLineFormatter {

    private static final String DEFAULT_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSX";

    /**
     * Constructs a new JsonFormatter.
     */
    public JsonFormatter() {
        String timeFormat = LogManager.getLogManager().getProperty(JsonFormatter.class.getName() + ".timeFormat");
        if (timeFormat == null) {
            timeFormat = DEFAULT_TIME_FORMAT;
        }
        setTimeFormat(timeFormat);
    }

    @Override
    public String format(LogRecord record) {
        StringBuilder sb = new StringBuilder();
        sb.append('{');

        // Timestamp
        sb.append("\"time\": \"");
        addTimestamp(sb, record.getMillis());
        sb.append("\", ");

        // Severity
        sb.append("\"level\": \"");
        sb.append(record.getLevel().getLocalizedName());
        sb.append("\", ");

        // Thread
        sb.append("\"thread\": \"");
        sb.append(resolveThreadName(record));
        sb.append("\", ");

        // Source
        sb.append("\"class\": \"");
        sb.append(record.getSourceClassName());
        sb.append("\", ");
        sb.append("\"method\": \"");
        sb.append(record.getSourceMethodName());
        sb.append("\", ");

        // Message
        sb.append("\"message\": \"");
        sb.append(JSONFilter.escape(formatMessage(record)));

        Throwable t = record.getThrown();
        if (t != null) {
            sb.append("\", ");

            // Stack trace
            sb.append("\"throwable\": [");
            boolean first = true;
            do {
                if (!first) {
                    sb.append(',');
                } else {
                    first = false;
                }
                sb.append('\"').append(JSONFilter.escape(t.toString())).append('\"');
                for (StackTraceElement element : t.getStackTrace()) {
                    sb.append(',').append('\"').append(' ').append(JSONFilter.escape(element.toString())).append('\"');
                }
                t = t.getCause();
            } while (t != null);
            sb.append(']');
        } else {
            sb.append('\"');
        }

        sb.append('}');
        // New line for next record
        sb.append(System.lineSeparator());

        return sb.toString();
    }


    /**
     * Provides escaping of values so they can be included in a JSON document. Escaping is based on the definition of
     * JSON found in <a href="https://www.rfc-editor.org/rfc/rfc8259.html">RFC 8259</a>.
     */
    public static class JSONFilter {

        /**
         * Escape the given string.
         *
         * @param input the string
         *
         * @return the escaped string
         */
        public static String escape(String input) {
            return escape(input, 0, input.length()).toString();
        }

        /**
         * Escape the given char sequence.
         *
         * @param input  the char sequence
         * @param off    the offset on which escaping will start
         * @param length the length which should be escaped
         *
         * @return the escaped char sequence corresponding to the specified range
         */
        public static CharSequence escape(CharSequence input, final int off, final int length) {
            /*
             * While any character MAY be escaped, only U+0000 to U+001F (control characters), U+0022 (quotation mark)
             * and U+005C (reverse solidus) MUST be escaped.
             */
            StringBuilder escaped = null;
            int lastUnescapedStart = off;
            final int end = off + length;
            for (int i = off; i < end; i++) {
                char c = input.charAt(i);
                if (c < 0x20 || c == 0x22 || c == 0x5c || Character.isHighSurrogate(c) || Character.isLowSurrogate(c)) {
                    if (escaped == null) {
                        escaped = new StringBuilder(length + 20);
                    }
                    if (lastUnescapedStart < i) {
                        escaped.append(input.subSequence(lastUnescapedStart, i));
                    }
                    lastUnescapedStart = i + 1;
                    char popular = getPopularChar(c);
                    if (popular > 0) {
                        escaped.append('\\').append(popular);
                    } else {
                        int v = c;
                        escaped.append("\\u").append(Character.forDigit((v >>> 12) & 0xF, 16))
                                .append(Character.forDigit((v >>> 8) & 0xF, 16))
                                .append(Character.forDigit((v >>> 4) & 0xF, 16))
                                .append(Character.forDigit(v & 0xF, 16));
                    }
                }
            }
            if (escaped == null) {
                if (off == 0 && length == input.length()) {
                    return input;
                } else {
                    return input.subSequence(off, end);
                }
            } else {
                if (lastUnescapedStart < end) {
                    escaped.append(input.subSequence(lastUnescapedStart, end));
                }
                return escaped.toString();
            }
        }

        private JSONFilter() {
            // Utility class. Hide the default constructor.
        }

        private static char getPopularChar(char c) {
            return switch (c) {
                case '"', '\\' -> c;
                case 0x8 -> 'b';
                case 0xc -> 'f';
                case 0xa -> 'n';
                case 0xd -> 'r';
                case 0x9 -> 't';
                default -> 0;
            };
        }
    }
}
