/*
 * 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.commons.net.ftp.parser;

import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.apache.commons.net.ftp.Configurable;
import org.apache.commons.net.ftp.FTPClientConfig;

/**
 * Default implementation of the {@link  FTPTimestampParser  FTPTimestampParser}
 * interface also implements the {@link  org.apache.commons.net.ftp.Configurable  Configurable}
 * interface to allow the parsing to be configured from the outside.
 *
 * @see ConfigurableFTPFileEntryParserImpl
 * @since 1.4
 */
public class FTPTimestampParserImpl implements
        FTPTimestampParser, Configurable
{


    /*
     * List of units in order of increasing significance.
     * This allows the code to clear all units in the Calendar until it
     * reaches the least significant unit in the parse string.
     * The date formats are analysed to find the least significant
     * unit (e.g. Minutes or Milliseconds) and the appropriate index to
     * the array is saved.
     * This is done by searching the array for the unit specifier,
     * and returning the index. When clearing the Calendar units,
     * the code loops through the array until the previous entry.
     * e.g. for MINUTE it would clear MILLISECOND and SECOND
     */
    private static final int[] CALENDAR_UNITS = {
        Calendar.MILLISECOND,
        Calendar.SECOND,
        Calendar.MINUTE,
        Calendar.HOUR_OF_DAY,
        Calendar.DAY_OF_MONTH,
        Calendar.MONTH,
        Calendar.YEAR};
    /*
     * Return the index to the array representing the least significant
     * unit found in the date format.
     * Default is 0 (to avoid dropping precision)
     */
    private static int getEntry(final SimpleDateFormat dateFormat) {
        if (dateFormat == null) {
            return 0;
        }
        final String FORMAT_CHARS="SsmHdM";
        final String pattern = dateFormat.toPattern();
        for(final char ch : FORMAT_CHARS.toCharArray()) {
            if (pattern.indexOf(ch) != -1){ // found the character
                switch(ch) {
                case 'S':
                    return indexOf(Calendar.MILLISECOND);
                case 's':
                    return indexOf(Calendar.SECOND);
                case 'm':
                    return indexOf(Calendar.MINUTE);
                case 'H':
                    return indexOf(Calendar.HOUR_OF_DAY);
                case 'd':
                    return indexOf(Calendar.DAY_OF_MONTH);
                case 'M':
                    return indexOf(Calendar.MONTH);
                }
            }
        }
        return 0;
    }

    /*
     * Find the entry in the CALENDAR_UNITS array.
     */
    private static int indexOf(final int calendarUnit) {
        int i;
        for(i = 0; i <CALENDAR_UNITS.length; i++) {
            if (calendarUnit == CALENDAR_UNITS[i]) {
                return i;
            }
        }
        return 0;
    }
    /*
     * Sets the Calendar precision (used by FTPFile#toFormattedDate) by clearing
     * the immediately preceeding unit (if any).
     * Unfortunately the clear(int) method results in setting all other units.
     */
    private static void setPrecision(final int index, final Calendar working) {
        if (index <= 0) { // e.g. MILLISECONDS
            return;
        }
        final int field = CALENDAR_UNITS[index-1];
        // Just in case the analysis is wrong, stop clearing if
        // field value is not the default.
        final int value = working.get(field);
        if (value != 0) { // don't reset if it has a value
//            new Throwable("Unexpected value "+value).printStackTrace(); // DEBUG
        } else {
            working.clear(field); // reset just the required field
        }
    }

    /** The date format for all dates, except possibly recent dates. Assumed to include the year. */
    private SimpleDateFormat defaultDateFormat;

    /* The index in CALENDAR_UNITS of the smallest time unit in defaultDateFormat */
    private int defaultDateSmallestUnitIndex;

    /** The format used for recent dates (which don't have the year). May be null. */
    private SimpleDateFormat recentDateFormat;

    /* The index in CALENDAR_UNITS of the smallest time unit in recentDateFormat */
    private int recentDateSmallestUnitIndex;

    private boolean lenientFutureDates;

    /**
     * The only constructor for this class.
     */
    public FTPTimestampParserImpl() {
        setDefaultDateFormat(DEFAULT_SDF, null);
        setRecentDateFormat(DEFAULT_RECENT_SDF, null);
    }

    /**
     * Implementation of the {@link  Configurable  Configurable}
     * interface. Configures this <code>FTPTimestampParser</code> according
     * to the following logic:
     * <p>
     * Set up the {@link  FTPClientConfig#setDefaultDateFormatStr(java.lang.String) defaultDateFormat}
     * and optionally the {@link  FTPClientConfig#setRecentDateFormatStr(String) recentDateFormat}
     * to values supplied in the config based on month names configured as follows:
     * </p>
     * <ul>
     * <li>If a {@link  FTPClientConfig#setShortMonthNames(String) shortMonthString}
     * has been supplied in the <code>config</code>, use that to parse  parse timestamps.</li>
     * <li>Otherwise, if a {@link  FTPClientConfig#setServerLanguageCode(String) serverLanguageCode}
     * has been supplied in the <code>config</code>, use the month names represented
     * by that {@link  FTPClientConfig#lookupDateFormatSymbols(String) language}
     * to parse timestamps.</li>
     * <li>otherwise use default English month names</li>
     * </ul><p>
     * Finally if a {@link  org.apache.commons.net.ftp.FTPClientConfig#setServerTimeZoneId(String) serverTimeZoneId}
     * has been supplied via the config, set that into all date formats that have
     * been configured.
     * </p>
     */
    @Override
    public void configure(final FTPClientConfig config) {
        DateFormatSymbols dfs = null;

        final String languageCode = config.getServerLanguageCode();
        final String shortmonths = config.getShortMonthNames();
        if (shortmonths != null) {
            dfs = FTPClientConfig.getDateFormatSymbols(shortmonths);
        } else if (languageCode != null) {
            dfs = FTPClientConfig.lookupDateFormatSymbols(languageCode);
        } else {
            dfs = FTPClientConfig.lookupDateFormatSymbols("en");
        }


        final String recentFormatString = config.getRecentDateFormatStr();
        setRecentDateFormat(recentFormatString, dfs);

        final String defaultFormatString = config.getDefaultDateFormatStr();
        if (defaultFormatString == null) {
            throw new IllegalArgumentException("defaultFormatString cannot be null");
        }
        setDefaultDateFormat(defaultFormatString, dfs);

        setServerTimeZone(config.getServerTimeZoneId());

        this.lenientFutureDates = config.isLenientFutureDates();
    }

    /**
     * @return Returns the defaultDateFormat.
     */
    public SimpleDateFormat getDefaultDateFormat() {
        return defaultDateFormat;
    }

    /**
     * @return Returns the defaultDateFormat pattern string.
     */
    public String getDefaultDateFormatString() {
        return defaultDateFormat.toPattern();
    }
    /**
     * @return Returns the recentDateFormat.
     */
    public SimpleDateFormat getRecentDateFormat() {
        return recentDateFormat;
    }
    /**
     * @return Returns the recentDateFormat.
     */
    public String getRecentDateFormatString() {
        return recentDateFormat.toPattern();
    }
    /**
     * @return Returns the serverTimeZone used by this parser.
     */
    public TimeZone getServerTimeZone() {
        return this.defaultDateFormat.getTimeZone();
    }
    /**
     * @return returns an array of 12 strings representing the short
     * month names used by this parse.
     */
    public String[] getShortMonths() {
        return defaultDateFormat.getDateFormatSymbols().getShortMonths();
    }
    /**
     * @return Returns the lenientFutureDates.
     */
    boolean isLenientFutureDates() {
        return lenientFutureDates;
    }

    /**
     * Implements the one {@link  FTPTimestampParser#parseTimestamp(String)  method}
     * in the {@link  FTPTimestampParser  FTPTimestampParser} interface
     * according to this algorithm:
     *
     * If the recentDateFormat member has been defined, try to parse the
     * supplied string with that.  If that parse fails, or if the recentDateFormat
     * member has not been defined, attempt to parse with the defaultDateFormat
     * member.  If that fails, throw a ParseException.
     *
     * This method assumes that the server time is the same as the local time.
     *
     * @see FTPTimestampParserImpl#parseTimestamp(String, Calendar)
     *
     * @param timestampStr The timestamp to be parsed
     * @return a Calendar with the parsed timestamp
     */
    @Override
    public Calendar parseTimestamp(final String timestampStr) throws ParseException {
        final Calendar now = Calendar.getInstance();
        return parseTimestamp(timestampStr, now);
    }


    /**
     * If the recentDateFormat member has been defined, try to parse the
     * supplied string with that.  If that parse fails, or if the recentDateFormat
     * member has not been defined, attempt to parse with the defaultDateFormat
     * member.  If that fails, throw a ParseException.
     *
     * This method allows a {@link Calendar} instance to be passed in which represents the
     * current (system) time.
     *
     * @see FTPTimestampParser#parseTimestamp(String)
     * @param timestampStr The timestamp to be parsed
     * @param serverTime The current time for the server
     * @return the calendar
     * @throws ParseException if timestamp cannot be parsed
     * @since 1.5
     */
    public Calendar parseTimestamp(final String timestampStr, final Calendar serverTime) throws ParseException {
        final Calendar working = (Calendar) serverTime.clone();
        working.setTimeZone(getServerTimeZone()); // is this needed?

        Date parsed = null;

        if (recentDateFormat != null) {
            final Calendar now = (Calendar) serverTime.clone();// Copy this, because we may change it
            now.setTimeZone(this.getServerTimeZone());
            if (lenientFutureDates) {
                // add a day to "now" so that "slop" doesn't cause a date
                // slightly in the future to roll back a full year.  (Bug 35181 => NET-83)
                now.add(Calendar.DAY_OF_MONTH, 1);
            }
            // The Java SimpleDateFormat class uses the epoch year 1970 if not present in the input
            // As 1970 was not a leap year, it cannot parse "Feb 29" correctly.
            // Java 1.5+ returns Mar 1 1970
            // Temporarily add the current year to the short date time
            // to cope with short-date leap year strings.
            // Since Feb 29 is more that 6 months from the end of the year, this should be OK for
            // all instances of short dates which are +- 6 months from current date.
            // TODO this won't always work for systems that use short dates +0/-12months
            // e.g. if today is Jan 1 2001 and the short date is Feb 29
            final String year = Integer.toString(now.get(Calendar.YEAR));
            final String timeStampStrPlusYear = timestampStr + " " + year;
            final SimpleDateFormat hackFormatter = new SimpleDateFormat(recentDateFormat.toPattern() + " yyyy",
                    recentDateFormat.getDateFormatSymbols());
            hackFormatter.setLenient(false);
            hackFormatter.setTimeZone(recentDateFormat.getTimeZone());
            final ParsePosition pp = new ParsePosition(0);
            parsed = hackFormatter.parse(timeStampStrPlusYear, pp);
            // Check if we parsed the full string, if so it must have been a short date originally
            if (parsed != null && pp.getIndex() == timeStampStrPlusYear.length()) {
                working.setTime(parsed);
                if (working.after(now)) { // must have been last year instead
                    working.add(Calendar.YEAR, -1);
                }
                setPrecision(recentDateSmallestUnitIndex, working);
                return working;
            }
        }

        final ParsePosition pp = new ParsePosition(0);
        parsed = defaultDateFormat.parse(timestampStr, pp);
        // note, length checks are mandatory for us since
        // SimpleDateFormat methods will succeed if less than
        // full string is matched.  They will also accept,
        // despite "leniency" setting, a two-digit number as
        // a valid year (e.g. 22:04 will parse as 22 A.D.)
        // so could mistakenly confuse an hour with a year,
        // if we don't insist on full length parsing.
        if ((parsed == null) || (pp.getIndex() != timestampStr.length())) {
            throw new ParseException(
                    "Timestamp '"+timestampStr+"' could not be parsed using a server time of "
                        +serverTime.getTime().toString(),
                    pp.getErrorIndex());
        }
        working.setTime(parsed);
        setPrecision(defaultDateSmallestUnitIndex, working);
        return working;
    }
    /**
     * @param format The defaultDateFormat to be set.
     * @param dfs the symbols to use (may be null)
     */
    private void setDefaultDateFormat(final String format, final DateFormatSymbols dfs) {
        if (format != null) {
            if (dfs != null) {
                this.defaultDateFormat = new SimpleDateFormat(format, dfs);
            } else {
                this.defaultDateFormat = new SimpleDateFormat(format);
            }
            this.defaultDateFormat.setLenient(false);
        } else {
            this.defaultDateFormat = null;
        }
        this.defaultDateSmallestUnitIndex = getEntry(this.defaultDateFormat);
    }

    /**
     * @param lenientFutureDates The lenientFutureDates to set.
     */
    void setLenientFutureDates(final boolean lenientFutureDates) {
        this.lenientFutureDates = lenientFutureDates;
    }
    /**
     * @param format The recentDateFormat to set.
     * @param dfs the symbols to use (may be null)
     */
    private void setRecentDateFormat(final String format, final DateFormatSymbols dfs) {
        if (format != null) {
            if (dfs != null) {
                this.recentDateFormat = new SimpleDateFormat(format, dfs);
            } else {
                this.recentDateFormat = new SimpleDateFormat(format);
            }
            this.recentDateFormat.setLenient(false);
        } else {
            this.recentDateFormat = null;
        }
        this.recentDateSmallestUnitIndex = getEntry(this.recentDateFormat);
    }
    /**
     * sets a TimeZone represented by the supplied ID string into all
     * of the parsers used by this server.
     * @param serverTimeZoneId Time Id java.util.TimeZone id used by
     * the ftp server.  If null the client's local time zone is assumed.
     */
    private void setServerTimeZone(final String serverTimeZoneId) {
        TimeZone serverTimeZone = TimeZone.getDefault();
        if (serverTimeZoneId != null) {
            serverTimeZone = TimeZone.getTimeZone(serverTimeZoneId);
        }
        this.defaultDateFormat.setTimeZone(serverTimeZone);
        if (this.recentDateFormat != null) {
            this.recentDateFormat.setTimeZone(serverTimeZone);
        }
    }
}
