/*
 *  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.vysper.xmpp.datetime;

import static org.apache.vysper.compliance.SpecCompliant.ComplianceCoverage.COMPLETE;
import static org.apache.vysper.compliance.SpecCompliant.ComplianceStatus.IN_PROGRESS;

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.time.FastDateFormat;
import org.apache.vysper.compliance.SpecCompliant;

/**
 * provides dates and times in XMPP conformant formats
 */
@SpecCompliant(spec = "XEP-0082", status = IN_PROGRESS, coverage = COMPLETE)
public class DateTimeProfile {

    protected static final TimeZone TIME_ZONE_UTC;

    protected static final FastDateFormat utcDateFormatter;

    protected static final FastDateFormat utcDateTimeFormatter;

    protected static final FastDateFormat utcTimeFormatter;

    private static final String DATE_PATTERN_VALUE = "(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)";

    private static final String TIME_PATTERN_VALUE = "(\\d\\d):(\\d\\d):(\\d\\d)";

    private static final String TZ_PATTERN_VALUE = "(([+-]\\d\\d:\\d\\d)|Z)";

    // time zone is required for date times
    private static final Pattern DATE_TIME_PATTERN = Pattern.compile("^" + DATE_PATTERN_VALUE + "T"
            + TIME_PATTERN_VALUE + TZ_PATTERN_VALUE + "$");

    private static final Pattern DATE_PATTERN = Pattern.compile("^" + DATE_PATTERN_VALUE + "$");

    // time zone is optional for times
    private static final Pattern TIME_PATTERN = Pattern.compile("^" + TIME_PATTERN_VALUE + TZ_PATTERN_VALUE + "?$");

    static {
        TIME_ZONE_UTC = TimeZone.getTimeZone("UTC");
        utcDateTimeFormatter = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss'Z'", TIME_ZONE_UTC);
        utcDateFormatter = FastDateFormat.getInstance("yyyy-MM-dd", TIME_ZONE_UTC);
        utcTimeFormatter = FastDateFormat.getInstance("HH:mm:ss'Z'", TIME_ZONE_UTC);
    }

    private final static DateTimeProfile SINGLETON = new DateTimeProfile();

    public static DateTimeProfile getInstance() {
        return SINGLETON;
    }

    protected DateTimeProfile() {
        // empty
    }

    public String getDateTimeInUTC(Date time) {
        return utcDateTimeFormatter.format(time);
    }

    public String getDateInUTC(Date time) {
        return utcDateFormatter.format(time);
    }

    public String getTimeInUTC(Date time) {
        return utcTimeFormatter.format(time);
    }

    /**
     * Parses a date time compliant with ISO-8601 and XEP-0082.
     * @param time The date time string
     * @return A {@link Calendar} representing the date time, in the
     *  time zone specified by the input string
     * @throws IllegalArgumentException If the input string is not a valid date time
     *  e.g. the time zone is missing
     */
    public Calendar fromDateTime(String time) {
        Matcher matcher = DATE_TIME_PATTERN.matcher(time);

        if (matcher.find()) {
            int year = Integer.valueOf(matcher.group(1));
            int month = Integer.valueOf(matcher.group(2));
            int day = Integer.valueOf(matcher.group(3));
            int hour = Integer.valueOf(matcher.group(4));
            int minute = Integer.valueOf(matcher.group(5));
            int second = Integer.valueOf(matcher.group(6));
            String tzValue = matcher.group(7);
            TimeZone tz;
            if (tzValue.equals("Z")) {
                tz = TIME_ZONE_UTC;
            } else {
                tz = TimeZone.getTimeZone("GMT" + tzValue);
            }
            Calendar calendar = Calendar.getInstance(tz);
            calendar.clear();
            calendar.set(year, month - 1, day, hour, minute, second);
            return calendar;
        } else {
            throw new IllegalArgumentException("Invalid date time: " + time);
        }
    }

    /**
     * Parses a time, compliant with ISO-8601 and XEP-0082.
     * @param time The time string
     * @return A {@link Calendar} representing the time, in the
     *  time zone specified by the input string. If a time zone is not specified
     *  in the input string, the returned {@link Calendar} will be in the UTC time zone
     * @throws IllegalArgumentException If the input string is not a valid time
     */
    public Calendar fromTime(String time) {
        Matcher matcher = TIME_PATTERN.matcher(time);

        if (matcher.find()) {
            int hour = Integer.valueOf(matcher.group(1));
            int minute = Integer.valueOf(matcher.group(2));
            int second = Integer.valueOf(matcher.group(3));
            String tzValue = matcher.group(4);
            TimeZone tz;
            if (tzValue == null || tzValue.equals("Z")) {
                tz = TIME_ZONE_UTC;
            } else {
                tz = TimeZone.getTimeZone("GMT" + tzValue);
            }
            Calendar calendar = Calendar.getInstance(tz);
            calendar.clear();
            calendar.set(Calendar.HOUR_OF_DAY, hour);
            calendar.set(Calendar.MINUTE, minute);
            calendar.set(Calendar.SECOND, second);
            return calendar;
        } else {
            throw new IllegalArgumentException("Invalid date time: " + time);
        }
    }

    /**
     * Parses a date, compliant with ISO-8601 and XEP-0082.
     * @param time The date string
     * @return A {@link Calendar} representing the date
     * @throws IllegalArgumentException If the input string is not a valid date
     */
    public Calendar fromDate(String time) {
        Matcher matcher = DATE_PATTERN.matcher(time);

        if (matcher.find()) {
            int year = Integer.valueOf(matcher.group(1));
            int month = Integer.valueOf(matcher.group(2));
            int day = Integer.valueOf(matcher.group(3));

            Calendar calendar = Calendar.getInstance(TIME_ZONE_UTC);
            calendar.clear();
            calendar.set(year, month - 1, day);
            return calendar;
        } else {
            throw new IllegalArgumentException("Invalid date time: " + time);
        }
    }
}
