/*******************************************************************************
 * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation
 *
 ******************************************************************************/
package org.eclipse.persistence.tools.utility;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.StringTokenizer;

/**
 * This comparator can be used to compare version strings
 * (e.g. <code>"2.2.2"</code> vs. <code>"2.14.3"</code>).
 * Clients can specify the delimiter(s) that separates a version's
 * <em>segments</em> as well as a parser to be used for parsing each
 * <em>segment</em>.
 *
 * @see #INTEGER_VERSION_COMPARATOR
 */
@SuppressWarnings("nls")
public class VersionComparator<T extends Comparable<T>>
	implements Comparator<String>
{
	private final String delimiters;
	private final SegmentParser<T> segmentParser;


	/**
	 * Static implementation of the version comparator interface that converts
	 * each version into a series of integers and compares them.
	 * <p>
	 * <strong>NB:</strong> With this comparator
	 * <code>"2.<strong>14</strong>" > "2.<strong>2</strong>"</code>
	 * is <code>true</code>.
	 */
	public static final Comparator<String> INTEGER_VERSION_COMPARATOR = new VersionComparator<Integer>(SegmentParser.IntegerSegmentParser.instance());


	/**
	 * Use the specified segment parser.
	 * The default delimiter is <code>'.'</code>.
	 */
	public VersionComparator(SegmentParser<T> segmentParser) {
		this(".", segmentParser);
	}

	/**
	 * Use the specified delimiters and segment parser.
	 */
	public VersionComparator(char delimiter, SegmentParser<T> segmentParser) {
		this(new char[] {delimiter}, segmentParser);
	}

	/**
	 * Use the specified delimiters and segment parser.
	 */
	public VersionComparator(char[] delimiters, SegmentParser<T> segmentParser) {
		this(new String(delimiters), segmentParser);
	}

	/**
	 * Use the specified delimiters and segment parser.
	 */
	public VersionComparator(String delimiters, SegmentParser<T> segmentParser) {
		super();
		if ((delimiters == null) || (segmentParser == null)) {
			throw new NullPointerException();
		}
		this.delimiters = delimiters;
		this.segmentParser = segmentParser;
	}


	/**
	 * <strong>NB:</strong> Callers must handle any runtime exceptions thrown by the
	 * segment parser supplied to the comparator. In particular, the pre-built
	 * integer segment parser {@link #INTEGER_VERSION_COMPARATOR} can throw a
	 * {@link NumberFormatException} if any segement string contains non-numeric
	 * characters.
	 */
	@Override
	public int compare(String version1, String version2) {
		ArrayList<T> segments1 = this.parseVersion(version1);
		ArrayList<T> segments2 = this.parseVersion(version2);
		int size1 = segments1.size();
		int size2 = segments2.size();
		int min = Math.min(size1, size2);
		for (int i = 0; i < min; i++) {
			int segmentCompare = segments1.get(i).compareTo(segments2.get(i));
			if (segmentCompare != 0) {
				return segmentCompare;
			}
		}

		if (size1 == size2) {
			return 0;
		}

		int max = Math.max(size1, size2);
		T zero = this.getZero();
		if (size1 < size2) {
			for (int i = min; i < max; i++) {
				int segmentCompare = zero.compareTo(segments2.get(i));
				if (segmentCompare != 0) {
					return segmentCompare;
				}
			}
		} else {
			for (int i = min; i < max; i++) {
				int segmentCompare = segments1.get(i).compareTo(zero);
				if (segmentCompare != 0) {
					return segmentCompare;
				}
			}
		}
		return 0;
	}

	/**
	 * Parse the specified version into a list of segments that can be
	 * compared individually.
	 */
	protected ArrayList<T> parseVersion(String s) {
		ArrayList<T> segments = new ArrayList<T>();
		int i = 0;
		for (StringTokenizer stream = new StringTokenizer(s, this.delimiters); stream.hasMoreTokens(); ) {
			segments.add(this.segmentParser.parse(i++, stream.nextToken()));
		}
		return segments;
	}

	protected T getZero() {
		return this.segmentParser.getZero();
	}


	/**
	 * A segment parser is used by a version comparator to convert each
	 * <em>segment</em> of a version into something that can be compared to the
	 * corresponding <em>segment</em> in another version.
	 */
	public interface SegmentParser<T extends Comparable<T>> {
		/**
		 * Convert the specified version <em>segment</em> into something that
		 * can be compared to the corresponding <em>segment</em> in another
		 * version.
		 */
		T parse(int segmentIndex, String segment);

		/**
		 * Return a "zero" <em>segment</em> value that can be compared to
		 * trailing segments when two version have differing numbers of
		 * <em>segments</em>.
		 */
		T getZero();

		/**
		 * Singleton implementation of the segment parser interface that converts
		 * each segment into an integer, irrespective of position.
		 * <p>
		 * <strong>NB:</strong> With this parser <code>"2.14" > "2.2"</code>
		 */
		final class IntegerSegmentParser
			implements SegmentParser<Integer>, Serializable
		{
			public static final SegmentParser<Integer> INSTANCE = new IntegerSegmentParser();
			public static SegmentParser<Integer> instance() {
				return INSTANCE;
			}
			// ensure single instance
			private IntegerSegmentParser() {
				super();
			}
			// simply parse the segment as an integer
			@Override
			public Integer parse(int segmentIndex, String segment) {
				return Integer.valueOf(segment);
			}
			@Override
			public Integer getZero() {
				return ZERO;
			}
			private static final Integer ZERO = Integer.valueOf(0);
			@Override
			public String toString() {
				return ObjectTools.singletonToString(this);
			}
			private static final long serialVersionUID = 1L;
			private Object readResolve() {
				// replace this object with the singleton
				return INSTANCE;
			}
		}

		/**
		 * Singleton implementation of the segment parser interface that throws
		 * an exception if called.
		 */
		final class Disabled<S extends Comparable<S>>
			implements SegmentParser<S>, Serializable
		{
			@SuppressWarnings("rawtypes")
			public static final SegmentParser INSTANCE = new Disabled();
			@SuppressWarnings("unchecked")
			public static <R extends Comparable<R>> SegmentParser<R> instance() {
				return INSTANCE;
			}
			// ensure single instance
			private Disabled() {
				super();
			}
			// throw an exception
			@Override
			public S parse(int segmentIndex, String segment) {
				throw new UnsupportedOperationException();
			}
			@Override
			public S getZero() {
				throw new UnsupportedOperationException();
			}
			@Override
			public String toString() {
				return ObjectTools.singletonToString(this);
			}
			private static final long serialVersionUID = 1L;
			private Object readResolve() {
				// replace this object with the singleton
				return INSTANCE;
			}
		}
	}
}