/*
 * Copyright (C) 2011 Citrix Systems, Inc.  All rights reserved.
 * 
 * Licensed 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 com.cloud.bridge.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * @author Kelven Yang
 */
public class DateHelper {
    public static final TimeZone GMT_TIMEZONE = TimeZone.getTimeZone("GMT");
    public static final String YYYYMMDD_FORMAT = "yyyyMMddHHmmss";
    
	public static Date currentGMTTime() {
		return new Date();
	}
	
	public static SimpleDateFormat getGMTDateFormat(String format) {
		SimpleDateFormat df = new SimpleDateFormat(format);
		df.setTimeZone(TimeZone.getTimeZone("GMT"));
		return df;
	}
	
	public static Date parseDateString(TimeZone tz, String dateString) {
		return parseDateString(tz, dateString, "yyyy-MM-dd HH:mm:ss");
	}
	
	public static Date parseISO8601DateString(String dateString) throws ParseException {
        // -> SimpleDateFormat uses GMT[-+]hh:mm for the TZ so first we need to
		//    convert the string with this value
        SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssz" );
        
        //this is zero time so we need to add that TZ indicator for 
        if ( dateString.endsWith( "Z" )) {
             dateString = dateString.substring( 0, dateString.length() - 1) + "GMT-00:00";
        } 
        else 
        {    // -> -0700 is valid but we need to change it to -07:00 for SimpleDateFormat
        	 dateString = dateString.replaceFirst( "-(\\d\\d)(\\d\\d)", "-$1:$2" );
        	 
        	 int inset = 6;       
             String s0 = dateString.substring( 0, dateString.length() - inset );
             String s1 = dateString.substring( dateString.length() - inset, dateString.length() );
             dateString = s0 + "GMT" + s1;
        }
        
        //System.out.println( "parseDate: [" + dateString + "]" );
        return df.parse( dateString );
	}

	public static Date parseDateString(TimeZone tz, String dateString, String formatString) {
		DateFormat df = new SimpleDateFormat(formatString);
		df.setTimeZone(tz);
		
    	try {
    		return df.parse(dateString);
    	} catch (ParseException e) {
    		throw new IllegalArgumentException(e);
    	}
	}
	
	public static String getDateDisplayString(TimeZone tz, Date time) {
		return getDateDisplayString(tz, time, "yyyy-MM-dd HH:mm:ss");
	}
	
	public static String getDateDisplayString(TimeZone tz, Date time, String formatString) {
		DateFormat df = new SimpleDateFormat(formatString);
		df.setTimeZone(tz);
		
		return df.format(time);
	}
	
	public static Calendar toCalendar(Date dt) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(dt);
		return calendar;
	}
}
