/*
 * 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.io.PrintWriter;
import java.io.Serial;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Formatter;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;

/**
 * Provides same information as default log format but on a single line to make it easier to grep the logs. The only
 * exception is stacktraces which are always preceded by whitespace to make it simple to skip them.
 */
/*
 * Date processing based on AccessLogValve.
 */
public class OneLineFormatter extends Formatter {

    private static final Object threadMxBeanLock = new Object();
    private static volatile ThreadMXBean threadMxBean = null;
    private static final int THREAD_NAME_CACHE_SIZE = 10000;
    private static final ThreadLocal<ThreadNameCache> threadNameCache =
            ThreadLocal.withInitial(() -> new ThreadNameCache(THREAD_NAME_CACHE_SIZE));

    /* Timestamp format */
    private static final String DEFAULT_TIME_FORMAT = "dd-MMM-yyyy HH:mm:ss.SSS";

    /**
     * The size of our global date format cache
     */
    private static final int GLOBAL_CACHE_SIZE = 30;

    /**
     * The size of our thread local date format cache
     */
    private static final int LOCAL_CACHE_SIZE = 5;

    /**
     * Thread local date format cache.
     */
    private ThreadLocal<DateFormatCache> localDateCache;

    private volatile MillisHandling millisHandling = MillisHandling.APPEND;


    /**
     * Constructs a OneLineFormatter with the default time format from the log manager properties.
     */
    public OneLineFormatter() {
        String timeFormat = LogManager.getLogManager().getProperty(OneLineFormatter.class.getName() + ".timeFormat");
        if (timeFormat == null) {
            timeFormat = DEFAULT_TIME_FORMAT;
        }
        setTimeFormat(timeFormat);
    }


    /**
     * Specify the time format to use for time stamps in log messages.
     *
     * @param timeFormat The format to use using the {@link java.text.SimpleDateFormat} syntax
     */
    public void setTimeFormat(final String timeFormat) {
        final String cachedTimeFormat;

        if (timeFormat.endsWith(".SSS")) {
            cachedTimeFormat = timeFormat.substring(0, timeFormat.length() - 4);
            millisHandling = MillisHandling.APPEND;
        } else if (timeFormat.contains("SSS")) {
            millisHandling = MillisHandling.REPLACE_SSS;
            cachedTimeFormat = timeFormat;
        } else if (timeFormat.contains("SS")) {
            millisHandling = MillisHandling.REPLACE_SS;
            cachedTimeFormat = timeFormat;
        } else if (timeFormat.contains("S")) {
            millisHandling = MillisHandling.REPLACE_S;
            cachedTimeFormat = timeFormat;
        } else {
            millisHandling = MillisHandling.NONE;
            cachedTimeFormat = timeFormat;
        }

        final DateFormatCache globalDateCache = new DateFormatCache(GLOBAL_CACHE_SIZE, cachedTimeFormat, null);
        localDateCache =
                ThreadLocal.withInitial(() -> new DateFormatCache(LOCAL_CACHE_SIZE, cachedTimeFormat, globalDateCache));
    }


    /**
     * Obtain the format currently being used for time stamps in log messages.
     *
     * @return The current format in {@link java.text.SimpleDateFormat} syntax
     */
    public String getTimeFormat() {
        return localDateCache.get().getTimeFormat();
    }


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

        // Timestamp
        addTimestamp(sb, record.getMillis());

        // Severity
        sb.append(' ');
        sb.append(record.getLevel().getLocalizedName());

        // Thread
        sb.append(' ');
        sb.append('[');
        sb.append(resolveThreadName(record));
        sb.append(']');

        // Source
        sb.append(' ');
        sb.append(record.getSourceClassName());
        sb.append('.');
        sb.append(record.getSourceMethodName());

        // Message
        sb.append(' ');
        sb.append(LogUtil.escape(formatMessage(record)));

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

        // Stack trace
        if (record.getThrown() != null) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new IndentingPrintWriter(sw);
            record.getThrown().printStackTrace(pw);
            pw.close();
            sb.append(LogUtil.escape(sw.toString()));
        }

        return sb.toString();
    }

    /**
     * Resolves the thread name for a log record, handling async handler cases.
     *
     * @param record The log record
     * @return The resolved thread name
     */
    protected String resolveThreadName(LogRecord record) {
        final String threadName = Thread.currentThread().getName();
        if (threadName != null && threadName.startsWith(AsyncFileHandler.THREAD_PREFIX)) {
            // If using the async handler can't get the thread name from the
            // current thread.
            return getThreadName(record.getLongThreadID());
        } else {
            return threadName;
        }
    }

    /**
     * Adds a formatted timestamp to the given buffer.
     *
     * @param buf The string builder to append to
     * @param timestamp The timestamp in milliseconds
     */
    protected void addTimestamp(StringBuilder buf, long timestamp) {
        String cachedTimeStamp = localDateCache.get().getFormat(timestamp);
        if (millisHandling == MillisHandling.NONE) {
            buf.append(cachedTimeStamp);
        } else if (millisHandling == MillisHandling.APPEND) {
            buf.append(cachedTimeStamp);
            long frac = timestamp % 1000;
            buf.append('.');
            if (frac < 100) {
                if (frac < 10) {
                    buf.append('0');
                    buf.append('0');
                } else {
                    buf.append('0');
                }
            }
            buf.append(frac);
        } else {
            // Some version of replace
            long frac = timestamp % 1000;
            // Formatted string may vary in length so the insert point may vary
            int insertStart = cachedTimeStamp.indexOf(DateFormatCache.MSEC_PATTERN);
            buf.append(cachedTimeStamp.subSequence(0, insertStart));
            if (frac < 100 && millisHandling == MillisHandling.REPLACE_SSS) {
                buf.append('0');
                if (frac < 10) {
                    buf.append('0');
                }
            } else if (frac < 10 && millisHandling == MillisHandling.REPLACE_SS) {
                buf.append('0');
            }
            buf.append(frac);
            if (millisHandling == MillisHandling.REPLACE_SSS) {
                buf.append(cachedTimeStamp.substring(insertStart + 3));
            } else if (millisHandling == MillisHandling.REPLACE_SS) {
                buf.append(cachedTimeStamp.substring(insertStart + 2));
            } else {
                buf.append(cachedTimeStamp.substring(insertStart + 1));
            }
        }
    }


    /**
     * LogRecord has threadID but no thread name.
     *
     * @param logRecordThreadId the thread id
     *
     * @return the thread name
     */
    protected static String getThreadName(long logRecordThreadId) {
        Map<Long,String> cache = threadNameCache.get();
        String result = cache.get(Long.valueOf(logRecordThreadId));

        if (result != null) {
            return result;
        }

        // Double-checked locking OK as threadMxBean is volatile
        if (threadMxBean == null) {
            synchronized (threadMxBeanLock) {
                if (threadMxBean == null) {
                    threadMxBean = ManagementFactory.getThreadMXBean();
                }
            }
        }
        ThreadInfo threadInfo = threadMxBean.getThreadInfo(logRecordThreadId);
        if (threadInfo == null) {
            return Long.toString(logRecordThreadId);
        }
        result = threadInfo.getThreadName();

        cache.put(Long.valueOf(logRecordThreadId), result);

        return result;
    }


    /*
     * This is an LRU cache.
     */
    private static class ThreadNameCache extends LinkedHashMap<Long,String> {

        @Serial
        private static final long serialVersionUID = 1L;

        private final int cacheSize;

        ThreadNameCache(int cacheSize) {
            super(cacheSize, 0.75f, true);
            this.cacheSize = cacheSize;
        }

        @Override
        protected boolean removeEldestEntry(Map.Entry<Long,String> eldest) {
            return (size() > cacheSize);
        }
    }


    /*
     * Minimal implementation to indent the printing of stack traces. This implementation depends on Throwable using
     * WrappedPrintWriter.
     */
    private static class IndentingPrintWriter extends PrintWriter {

        IndentingPrintWriter(Writer out) {
            super(out);
        }

        @Override
        public void println(Object x) {
            super.print('\t');
            super.println(x);
        }
    }


    private enum MillisHandling {
        NONE,
        APPEND,
        REPLACE_S,
        REPLACE_SS,
        REPLACE_SSS,
    }
}
