//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.util;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**  Date Format Cache.
 * Computes String representations of Dates and caches
 * the results so that subsequent requests within the same second
 * will be fast.
 *
 * Only format strings that contain either "ss".  Sub second formatting is 
 * not handled.
 *
 * The timezone of the date may be included as an ID with the "zzz"
 * format string or as an offset with the "ZZZ" format string.
 *
 * If consecutive calls are frequently very different, then this
 * may be a little slower than a normal DateFormat.
 */
public class DateCache
{
    public static final String DEFAULT_FORMAT="EEE MMM dd HH:mm:ss zzz yyyy";
    
    private final String _formatString;
    private final String _tzFormatString;
    private final SimpleDateFormat _tzFormat;
    private final Locale _locale ;
    
    private volatile Tick _tick;

    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    public static class Tick
    {
        final long _seconds;
        final String _string;
        public Tick(long seconds, String string)
        {
            _seconds = seconds;
            _string = string;
        }
    }

    /* ------------------------------------------------------------ */
    /** Constructor.
     * Make a DateCache that will use a default format. The default format
     * generates the same results as Date.toString().
     */
    public DateCache()
    {
        this(DEFAULT_FORMAT);
    }
    
    /* ------------------------------------------------------------ */
    /** Constructor.
     * Make a DateCache that will use the given format
     * @param format the format to use
     */
    public DateCache(String format)
    {
        this(format,null,TimeZone.getDefault());
    }
    
    /* ------------------------------------------------------------ */
    public DateCache(String format,Locale l)
    {
        this(format,l,TimeZone.getDefault());
    }

    /* ------------------------------------------------------------ */
    public DateCache(String format,Locale l,String tz)
    {
        this(format,l,TimeZone.getTimeZone(tz));
    }
    
    /* ------------------------------------------------------------ */
    public DateCache(String format,Locale l,TimeZone tz)
    {
        _formatString=format;
        _locale = l;
        

        int zIndex = _formatString.indexOf( "ZZZ" );
        if( zIndex >= 0 )
        {
            String ss1 = _formatString.substring( 0, zIndex );
            String ss2 = _formatString.substring( zIndex+3 );
            int tzOffset = tz.getRawOffset();
            
            StringBuilder sb = new StringBuilder(_formatString.length()+10);
            sb.append(ss1);
            sb.append("'");
            if( tzOffset >= 0 )
                sb.append( '+' );
            else
            {
                tzOffset = -tzOffset;
                sb.append( '-' );
            }
            
            int raw = tzOffset / (1000*60);             // Convert to seconds
            int hr = raw / 60;
            int min = raw % 60;
            
            if( hr < 10 )
                sb.append( '0' );
            sb.append( hr );
            if( min < 10 )
                sb.append( '0' );
            sb.append( min );
            sb.append( '\'' );
            
            sb.append(ss2);
            _tzFormatString=sb.toString();            
        }
        else
            _tzFormatString=_formatString;
   
        if( _locale != null ) 
        {
            _tzFormat=new SimpleDateFormat(_tzFormatString,_locale);
        }
        else 
        {
            _tzFormat=new SimpleDateFormat(_tzFormatString);
        }
        _tzFormat.setTimeZone(tz);
        
        _tick=null;
    }
    

    /* ------------------------------------------------------------ */
    public TimeZone getTimeZone()
    {
        return _tzFormat.getTimeZone();
    }


    /* ------------------------------------------------------------ */
    /** Format a date according to our stored formatter.
     * @param inDate the Date
     * @return Formatted date
     */
    public String format(Date inDate)
    {
        long seconds = inDate.getTime() / 1000;

        Tick tick=_tick;
        
        // Is this the cached time
        if (tick==null || seconds!=tick._seconds)
        {
            // It's a cache miss
            synchronized (this)
            {
                return _tzFormat.format(inDate);
            }
        }
        
        return tick._string;
    }
    
    /* ------------------------------------------------------------ */
    /** Format a date according to our stored formatter.
     * If it happens to be in the same second as the last formatNow
     * call, then the format is reused.
     * @param inDate the date in milliseconds since unix epoch 
     * @return Formatted date
     */
    public String format(long inDate)
    {
        long seconds = inDate / 1000;

        Tick tick=_tick;
        
        // Is this the cached time
        if (tick==null || seconds!=tick._seconds)
        {
            // It's a cache miss
            Date d = new Date(inDate);
            synchronized (this)
            {
                return _tzFormat.format(d);
            }
        }
        
        return tick._string;
    }
    
    /* ------------------------------------------------------------ */
    /** Format a date according to our stored formatter.
     * The passed time is expected to be close to the current time, so it is 
     * compared to the last value passed and if it is within the same second,
     * the format is reused.  Otherwise a new cached format is created.
     * @param now the milliseconds since unix epoch 
     * @return Formatted date
     */
    public String formatNow(long now)
    {
        long seconds = now / 1000;

        Tick tick=_tick;
        
        // Is this the cached time
        if (tick!=null && tick._seconds==seconds)
            return tick._string;
        return formatTick(now)._string;
    }
    
    /* ------------------------------------------------------------ */
    public String now()
    {
        return formatNow(System.currentTimeMillis());
    }
    
    /* ------------------------------------------------------------ */
    public Tick tick()
    {
        return formatTick(System.currentTimeMillis());
    }
    
    /* ------------------------------------------------------------ */
    protected Tick formatTick(long now)
    {
        long seconds = now / 1000;

        // Synchronize to protect _tzFormat
        synchronized (this)
        {
            // recheck the tick, to save multiple formats
            if (_tick==null || _tick._seconds!=seconds)
            {
                String s= _tzFormat.format(new Date(now));
                return _tick=new Tick(seconds,s);
            }
            return _tick;
        }
    }

    /* ------------------------------------------------------------ */
    public String getFormatString()
    {
        return _formatString;
    }    
}
