/*
 * 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.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**
 * <p>Cache structure for SimpleDateFormat formatted timestamps based on
 * seconds.</p>
 *
 * <p>Millisecond formatting using S is not supported. You should add the
 * millisecond information after getting back the second formatting.</p>
 *
 * <p>The cache consists of entries for a consecutive range of
 * seconds. The length of the range is configurable. It is
 * implemented based on a cyclic buffer. New entries shift the range.</p>
 *
 * <p>The cache is not threadsafe. It can be used without synchronization
 * via thread local instances, or with synchronization as a global cache.</p>
 *
 * <p>The cache can be created with a parent cache to build a cache hierarchy.
 * Access to the parent cache is threadsafe.</p>
 */
public class DateFormatCache {

    private static final String msecPattern = "#";

    /* Timestamp format */
    private final String format;

    /* Number of cached entries */
    private final int cacheSize;

    private final Cache cache;

    /**
     * Replace the millisecond formatting character 'S' by
     * some dummy characters in order to make the resulting
     * formatted time stamps cacheable. Our consumer might
     * choose to replace the dummy chars with the actual
     * milliseconds because that's relatively cheap.
     */
    private String tidyFormat(String format) {
        boolean escape = false;
        StringBuilder result = new StringBuilder();
        int len = format.length();
        char x;
        for (int i = 0; i < len; i++) {
            x = format.charAt(i);
            if (escape || x != 'S') {
                result.append(x);
            } else {
                result.append(msecPattern);
            }
            if (x == '\'') {
                escape = !escape;
            }
        }
        return result.toString();
    }

    public DateFormatCache(int size, String format, DateFormatCache parent) {
        cacheSize = size;
        this.format = tidyFormat(format);
        Cache parentCache = null;
        if (parent != null) {
            synchronized(parent) {
                parentCache = parent.cache;
            }
        }
        cache = new Cache(parentCache);
    }

    public String getFormat(long time) {
        return cache.getFormat(time);
    }

    private class Cache {

        /* Second formatted in most recent invocation */
        private long previousSeconds = Long.MIN_VALUE;
        /* Formatted timestamp generated in most recent invocation */
        private String previousFormat = "";

        /* First second contained in cache */
        private long first = Long.MIN_VALUE;
        /* Last second contained in cache */
        private long last = Long.MIN_VALUE;
        /* Index of "first" in the cyclic cache */
        private int offset = 0;
        /* Helper object to be able to call SimpleDateFormat.format(). */
        private final Date currentDate = new Date();

        private String cache[];
        private SimpleDateFormat formatter;

        private Cache parent = null;

        private Cache(Cache parent) {
            cache = new String[cacheSize];
            for (int i = 0; i < cacheSize; i++) {
                cache[i] = null;
            }
            formatter = new SimpleDateFormat(format, Locale.US);
            formatter.setTimeZone(TimeZone.getDefault());
            this.parent = parent;
        }

        private String getFormat(long time) {

            long seconds = time / 1000;

            /* First step: if we have seen this timestamp
               during the previous call, return the previous value. */
            if (seconds == previousSeconds) {
                return previousFormat;
            }

            /* Second step: Try to locate in cache */
            previousSeconds = seconds;
            int index = (offset + (int)(seconds - first)) % cacheSize;
            if (index < 0) {
                index += cacheSize;
            }
            if (seconds >= first && seconds <= last) {
                if (cache[index] != null) {
                    /* Found, so remember for next call and return.*/
                    previousFormat = cache[index];
                    return previousFormat;
                }

            /* Third step: not found in cache, adjust cache and add item */
            } else if (seconds >= last + cacheSize || seconds <= first - cacheSize) {
                first = seconds;
                last = first + cacheSize - 1;
                index = 0;
                offset = 0;
                for (int i = 1; i < cacheSize; i++) {
                    cache[i] = null;
                }
            } else if (seconds > last) {
                for (int i = 1; i < seconds - last; i++) {
                    cache[(index + cacheSize - i) % cacheSize] = null;
                }
                first = seconds - (cacheSize - 1);
                last = seconds;
                offset = (index + 1) % cacheSize;
            } else if (seconds < first) {
                for (int i = 1; i < first - seconds; i++) {
                    cache[(index + i) % cacheSize] = null;
                }
                first = seconds;
                last = seconds + (cacheSize - 1);
                offset = index;
            }

            /* Last step: format new timestamp either using
             * parent cache or locally. */
            if (parent != null) {
                synchronized(parent) {
                    previousFormat = parent.getFormat(time);
                }
            } else {
                currentDate.setTime(time);
                previousFormat = formatter.format(currentDate);
            }
            cache[index] = previousFormat;
            return previousFormat;
        }
    }
}
