/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.bpel.validator.tools;

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

import javax.xml.namespace.QName;

/**
 * @author Michal Chmielewski (michal.chmielewski@oracle.com)
 * @author Glenn Mi (glenn.me@oracle.com)
 * 
 * @date Sep 29, 2006
 * 
 */
public class ParserTool {

	private static final Locale INTERNAL_PARSE_LOCALE = Locale.US;

	private static final Locale INTERNAL_CAL_LOCALE = Locale.US;

	private static SimpleDateFormat zulu = new SimpleDateFormat(
			"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", INTERNAL_PARSE_LOCALE); //$NON-NLS-1$

	static {
		zulu.setTimeZone(TimeZone.getDefault());
	}

	/**
	 * Format date time string into the format:
	 *  2005-04-04T14:59:11.302-08:00
	 *  
	 * @param time
	 * @return the formatted date time string.
	 */
	
	public static String getDateTimeString(long time) {
		// 2005-04-04T14:59:11.302-08:00
		SimpleDateFormat xmlDateFormat = new SimpleDateFormat(
				"yyyy-MM-dd'T'HH:mm:ss.SSSZ", INTERNAL_PARSE_LOCALE); //$NON-NLS-1$
		Calendar cal = Calendar.getInstance(INTERNAL_CAL_LOCALE);
		cal.setTime(new Date(time));
		String javaFmt = xmlDateFormat.format(cal.getTime());

		int length = javaFmt.length();
		String dt = javaFmt.substring(0, length - 2);

		StringBuilder retVal = new StringBuilder(dt);
		retVal.append(":"); //$NON-NLS-1$
		retVal.append(javaFmt.substring(length - 2, length));

		return retVal.toString();
	}

	public static String getDateString(long time) {
		Calendar cal = Calendar.getInstance(INTERNAL_CAL_LOCALE);
		cal.setTime(new Date(time));
		SimpleDateFormat xmlDateFormat = new SimpleDateFormat(
				"yyyy-MM-dd", INTERNAL_PARSE_LOCALE); //$NON-NLS-1$
		return xmlDateFormat.format(cal.getTime());
	}

	/**
	 * parse XML duration in the format of P1Y2M3DT10H30M12.3S
	 * 
	 * @param src
	 * @return ?
	 * @throws IllegalArgumentException
	 */

	public static long parseDuration(String src)
			throws IllegalArgumentException {
		int years = 0;
		int months = 0;
		int days = 0;
		int hours = 0;
		int minutes = 0;
		double seconds = 0.;

		int idx = 0;
		int idx2 = 0;
		if (src.charAt(idx) != 'P')
			throw new IllegalArgumentException(
					"Duration has to start with 'P'."); //$NON-NLS-1$
		idx++;

		String dayPart = null;
		String timePart = null;

		idx2 = src.indexOf('T');
		if (idx2 > 0) {
			dayPart = src.substring(idx, idx2);
			timePart = src.substring(idx2 + 1);
		} else {
			dayPart = src.substring(idx);
		}

		try {
			String str;
			if (dayPart != null && dayPart.length() > 0) {
				// parse day part
				idx = 0;

				idx2 = dayPart.indexOf('Y');
				if (idx2 > 0) {
					str = dayPart.substring(idx, idx2);
					years = Integer.parseInt(str);
					idx = idx2 + 1;
				}

				idx2 = dayPart.indexOf('M');
				if (idx2 > 0) {
					str = dayPart.substring(idx, idx2);
					months = Integer.parseInt(str);
					idx = idx2 + 1;
				}

				idx2 = dayPart.indexOf('D');
				if (idx2 > 0) {
					str = dayPart.substring(idx, idx2);
					days = Integer.parseInt(str);
					idx = idx2 + 1;
				}

				if (dayPart.indexOf('H') >= 0 || dayPart.indexOf('S') >= 0)
					throw new NumberFormatException();
			}

			if (timePart != null) {
				// parse time part
				idx = 0;

				idx2 = timePart.indexOf('H');
				if (idx2 > 0) {
					str = timePart.substring(idx, idx2);
					hours = Integer.parseInt(str);
					idx = idx2 + 1;
				}

				idx2 = timePart.indexOf('M');
				if (idx2 > 0) {
					str = timePart.substring(idx, idx2);
					minutes = Integer.parseInt(str);
					idx = idx2 + 1;
				}

				idx2 = timePart.indexOf('S');
				if (idx2 > 0) {
					str = timePart.substring(idx, idx2);
					seconds = Double.parseDouble(str);
				}

				if (timePart.indexOf('Y') >= 0 || timePart.indexOf('D') >= 0)
					throw new NumberFormatException();
			}
		} catch (NumberFormatException e) {
			throw new IllegalArgumentException(
					"duration should be in the format of 'P1Y2M3DT10H30M12.3S'"); //$NON-NLS-1$
		}

		long duration = (long) (((((((years * 365 + months * 30) + days) * 24 + hours) * 60) + minutes) * 60 + seconds) * 1000);
		return duration;
	}

	/**
	 * Parse date string into a Date.
	 * 
	 * @param dateStr
	 * @return the date
	 */

	public static Date parseDate(String dateStr) {
		try {
			if( dateStr == null || dateStr.length() < 10 )
				throw new NumberFormatException("badDateTime"); //$NON-NLS-1$
			
			SimpleDateFormat df = new SimpleDateFormat(
					"yyyy-MM-dd", INTERNAL_PARSE_LOCALE); //$NON-NLS-1$
			return df.parse( dateStr );
			
		} catch (Exception e) {
			throw new NumberFormatException(e.toString());
		}
	}

	public static Date parseDateFromLong(String longString) {
		if (longString != null) {
			return new Date(Long.parseLong(longString));
		}
		return null;
	}

	public static Calendar parseDateTimeFromLong(String longString) {
		if (longString != null) {
			Calendar calendar = Calendar.getInstance(INTERNAL_CAL_LOCALE);
			calendar.setTime(new Date(Long.parseLong(longString)));
			return calendar;
		}
		return null;
	}

	public static Calendar parseDateTime(String source) {
		return parseDateAndTime(source);
	}

	/**
	 * The simple deserializer provides most of the stuff. We just need to
	 * override makeValue().
	 * 
	 * @param source
	 *            the source string to parse
	 * @return the Calandar instance that the string was parsed into
	 * 
	 */

	public static Calendar parseDateAndTime(String source) {
		if (source == null || isEmpty(source))
			return null;

		Calendar calendar = Calendar.getInstance(INTERNAL_CAL_LOCALE);
		Date date;
		boolean bc = false;

		// validate fixed portion of format
		if (source.charAt(0) == '+')
			source = source.substring(1);

		if (source.charAt(0) == '-') {
			source = source.substring(1);
			bc = true;
		}
		if (source.length() < 19) {
			throw new NumberFormatException("badDateTime"); //$NON-NLS-1$
		}

		if (source.charAt(4) != '-' || source.charAt(7) != '-'
				|| source.charAt(10) != 'T') {
			throw new NumberFormatException("badDate"); //$NON-NLS-1$
		}

		if (source.charAt(13) != ':' || source.charAt(16) != ':') {
			throw new NumberFormatException("badTime"); //$NON-NLS-1$
		}

		// convert what we have validated so far
		try {
			synchronized (zulu) {
				date = zulu.parse((source.substring(0, 19) + ".000Z")); //$NON-NLS-1$
			}
		} catch (Exception e) {
			throw new NumberFormatException(e.toString());
		}

		int pos = 19;

		// parse optional milliseconds
		if (pos < source.length() && source.charAt(pos) == '.') {
			int milliseconds = 0;
			int start = ++pos;
			while (pos < source.length()
					&& Character.isDigit(source.charAt(pos)))
				pos++;

			String decimal = source.substring(start, pos);
			if (decimal.length() == 3)
				milliseconds = Integer.parseInt(decimal);
			else if (decimal.length() < 3)
				milliseconds = Integer.parseInt((decimal + "000") //$NON-NLS-1$
						.substring(0, 3));
			else {
				milliseconds = Integer.parseInt(decimal.substring(0, 3));
				if (decimal.charAt(3) >= '5')
					++milliseconds;
			}

			// add milliseconds to the current date
			date.setTime(date.getTime() + milliseconds);
		}

		// parse optional timezone
		if (pos + 5 < source.length()
				&& (source.charAt(pos) == '+' || (source.charAt(pos) == '-'))) {
			if (!Character.isDigit(source.charAt(pos + 1))
					|| !Character.isDigit(source.charAt(pos + 2))
					|| source.charAt(pos + 3) != ':'
					|| !Character.isDigit(source.charAt(pos + 4))
					|| !Character.isDigit(source.charAt(pos + 5))) {
				throw new NumberFormatException("badTimezone"); //$NON-NLS-1$
			}

			// subtract milliseconds from current date to obtain GMT
			// if (source.charAt(pos)=='+') milliseconds=-milliseconds;
			// date.setTime(date.getTime()+milliseconds);
			pos += 6;
		}

		if (pos < source.length() && source.charAt(pos) == 'Z') {
			pos++;
			// calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
		}

		if (pos < source.length())
			throw new NumberFormatException("badChars");

		calendar.setTime(date);

		// support dates before the Christian era
		if (bc) {
			calendar.set(Calendar.ERA, GregorianCalendar.BC);
		}

		return calendar;
	}

	public static float parseFloat(String floatStr) {
		if (!isEmpty(floatStr)) {
			return Float.parseFloat(floatStr);
		}
		return 0f;
	}

	public static double parseDouble(String value) {
		String v = String.valueOf(value);
		if (!isEmpty(v)) {
			return Double.parseDouble(v);
		}
		return 0d;
	}

	public static int parseInt(String value) {
		try {
			if (!isEmpty(value)) {
				value = String.valueOf(adjustResult(value));
				return Integer.parseInt(value);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;

	}

	public static boolean parseBoolean(String value) {
		if (!isEmpty(value)) {
			return Boolean.valueOf( value );
		}
		return false;
	}

	public static short parseShort(String value) {
		if (!isEmpty(value)) {
			value = String.valueOf(adjustResult(value));
			return Short.parseShort(value);
		}
		return 0;
	}

	public static byte parseByte(String value) {
		if (!isEmpty(value)) {
			return Byte.parseByte(value);
		}
		return 0;
	}

	public static long parseLong(String value) {
		if (!isEmpty(value)) {
			return Long.parseLong(value);
		}
		return 0l;
	}

	public static char parseChar(String value) {
		if (!isEmpty(value)) {
			char arr[] = value.toCharArray();
			return arr[0];
		}
		return 0;
	}

	public static Object convertToObject(double d) {
		return Double.valueOf( d );
	}

	public static Object convertToObject(int d) {
		return Integer.valueOf( d );
	}

	public static Object convertToObject(char d) {
		return Character.valueOf( d );
	}

	public static Object convertToObject(byte d) {
		return Byte.valueOf( d );
	}

	public static Object convertToObject(short d) {
		return Short.valueOf( d );
	}

	public static Object convertToObject(long d) {
		return Long.valueOf( d );
	}

	public static Object convertToObject(float d) {
		return Float.valueOf( d );
	}

	public static Object convertToObject(Object d) {
		return d;
	}

	public static String convertToXMLString(Object value) {
		String xmlString = null;
		if (value != null) {
			// Conversion process:
			// Object -> Object
			// primitve -> String
			//
			Class type = value.getClass();
			if (type.isPrimitive()) {
				xmlString = primitiveToXMLString(value, type);
			} else if (value instanceof QName) {
				// calender
				QName qname = (QName) value;
				if (qname.getPrefix() != null && qname.getPrefix().length() > 0)
					xmlString = qname.getPrefix() + ":" + qname.getLocalPart();
				else
					xmlString = qname.getLocalPart();
			} else if (value instanceof Calendar) {
				// calender
				xmlString = calendarToXMLString((Calendar) value);
			} else if (value instanceof Date) {
				xmlString = dateToXMLString((Date) value);
			}
			// else if (value instanceof DateTimeBase)
			// {
			// xmlString = dateTimeToXMLString( (DateTimeBase) value );
			// }
			// else if (value instanceof Duration)
			// {
			// xmlString = durationToXMLString( (Duration) value );
			// }
			else {
				xmlString = String.valueOf(value);
			}

		}
		return xmlString;
	}

	// public static String durationToXMLString( Duration value )
	// {
	// return value != null ? value.toString() : "";
	// }
	//	    
	// public static String dateTimeToXMLString( DateTimeBase value )
	// {
	// return value != null ? calendarToXMLString( value.toCalendar() ) : "";
	// }
	//	    
	public static String dateToXMLString(Date value) {
		return value != null ? getDateString(value.getTime()) : "";
	}

	public static String calendarToXMLString(Calendar value) {
		return value != null ? getDateTimeString(value.getTime().getTime())
				: "";
	}

	public static String primitiveToXMLString(Object primitiveObject, Class type) {
		String xmlString = null;
		if (type == Double.class) {
			xmlString = ((Double) primitiveObject).toString();
		} else if (type == Integer.class) {
			xmlString = ((Integer) primitiveObject).toString();
		} else if (type == Boolean.class) {
			xmlString = ((Boolean) primitiveObject).toString();
		} else if (type == Float.class) {
			xmlString = ((Float) primitiveObject).toString();
		} else if (type == Byte.class) {
			xmlString = ((Byte) primitiveObject).toString();
		} else if (type == Short.class) {
			xmlString = ((Short) primitiveObject).toString();
		} else if (type == Long.class) {
			xmlString = ((Long) primitiveObject).toString();
		} else if (type == Character.class) {
			xmlString = ((Character) primitiveObject).toString();
		}
		return xmlString;
	}

	public static void main(String[] args) throws Exception {
		// System.out.println(parseDuration(args[0]));

		Date d = new Date();
		String dtStr = getDateTimeString(d.getTime());
		System.out.println("dateTime=" + dtStr);
		Calendar cal = parseDateTime(dtStr);
		System.out.println("cal is: " + cal);
		System.out.println("date is: " + cal.getTime());
		System.out.println("XML Datetime "
				+ getDateTimeString(cal.getTime().getTime()));
		System.out
				.println("XML Date " + getDateString(cal.getTime().getTime()));

	}

	private static Object adjustResult(String result) {
		if (result != null && result.indexOf(".") > 0) {
			String dS = result;

			int fracIndex = dS.indexOf(".");
			String fr = dS.substring(fracIndex + 1, dS.length());
			String in = dS.substring(0, fracIndex);
			// fraction = (n - abs(n))
			// if the fraction is 0 then assume that the result is an integer
			// and construct an integer object and return it.
			//
			// TODO: FIXME Once we have schema types then we should do proper
			// typed return value
			// System.out.println("___________ fraction : " + fr );
			// System.out.println("___________ before decimal : " + in );
			Double d1 = new Double(fr);
			if (d1.doubleValue() == 0) {
				return new Integer(in);
			}
		}
		return result;
	}

	/**
	 * Returns true if the string is either null or contains just whitespace.
	 */

	static boolean isEmpty(String value) {
		if (value == null || value.length() == 0) {
			return true;
		}
		for (int i = 0, j = value.length(); i < j; i++) {
			if (!Character.isWhitespace(value.charAt(i))) {
				return false;
			}
		}
		return true;
	}
}
