/*******************************************************************************
 * Copyright (c) 2009 Cloudsmith Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Cloudsmith Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.internal.provisional.p2.core;

import java.io.Serializable;

/**
 * The VersionVector represents an array of Comparable objects. The array can be
 * nested since a VersionVector is Comparable in itself.
 *  
 * @Immutable
 */
public class VersionVector implements Comparable, Serializable {

	private static final class MaxStringValue implements Comparable, Serializable {
		private static final long serialVersionUID = -4936252230441132767L;

		MaxStringValue() {
			// Empty constructor
		}

		public int compareTo(Object o) {
			return o == this ? 0 : (o == MAX_VALUE || o instanceof Integer || o instanceof VersionVector ? -1 : 1);
		}

		// For singleton deserialization
		private Object readResolve() {
			return MAXS_VALUE;
		}

		public String toString() {
			return "m"; //$NON-NLS-1$
		}
	}

	private static final class MaxValue implements Comparable, Serializable {
		private static final long serialVersionUID = -5889641741635253589L;

		MaxValue() {
			// Empty constructor
		}

		public int compareTo(Object o) {
			return o == this ? 0 : 1;
		}

		public String toString() {
			return "M"; //$NON-NLS-1$
		}

		// For singleton deserialization
		private Object readResolve() {
			return MAX_VALUE;
		}
	}

	private static class MinValue implements Comparable, Serializable {
		private static final long serialVersionUID = -1066323980049812226L;

		MinValue() {
			// Empty constructor
		}

		public int compareTo(Object o) {
			return o == this ? 0 : -1;
		}

		public String toString() {
			return "-M"; //$NON-NLS-1$
		}

		private Object readResolve() {
			return MIN_VALUE;
		}
	}

	/**
	 * A value that is greater then any other value
	 */
	public static final Comparable MAX_VALUE = new MaxValue();

	/**
	 * A value that is greater then any string but less then {@link #MAX_VALUE} and
	 * any Integer or VersionVector.
	 */
	public static final Comparable MAXS_VALUE = new MaxStringValue();

	/**
	 * A value that is less then any other value
	 */
	public static final Comparable MIN_VALUE = new MinValue();

	private static final long serialVersionUID = -8385373304298723744L;

	static void rawToString(StringBuffer sb, boolean forRange, Comparable e) {
		if (e instanceof String) {
			writeQuotedString(sb, forRange, (String) e, '\'', 0, false);
		} else if (e instanceof VersionVector) {
			sb.append('<');
			((VersionVector) e).toString(sb, forRange);
			sb.append('>');
		} else
			sb.append(e);
	}

	/**
	 * Write a string within quotes. If the string is found to contain the quote, an attempt is made
	 * to flip quote character (single quote becomes double quote and vice versa). A string that contains
	 * both will be written as several adjacent quoted strings so that each string is quoted with a
	 * quote character that it does not contain.
	 * @param sb The buffer that will receive the string
	 * @param rangeSafe Set to <code>true</code> if the resulting string will be used in a range string
	 *        and hence need to escape the range delimiter characters
	 * @param s The string to be written
	 * @param quote The quote character to start with. Must be the single or double quote character.
	 * @param startPos The start position
	 * @param didFlip True if the call is recursive and thus, cannot switch quotes in the first string.
	 */
	static void writeQuotedString(StringBuffer sb, boolean rangeSafe, String s, char quote, int startPos, boolean didFlip) {
		int quotePos = sb.length();
		sb.append(quote);
		boolean otherSeen = false;
		int top = s.length();
		for (int idx = startPos; idx < top; ++idx) {
			char c = s.charAt(idx);
			if (c == '\'' || c == '"') {
				if (c == quote) {
					char otherQuote = quote == '\'' ? '"' : '\'';
					if (didFlip || otherSeen) {
						// We can only flip once
						sb.append(quote);
						writeQuotedString(sb, rangeSafe, s, otherQuote, idx, true);
						return;
					}
					quote = otherQuote;
					sb.setCharAt(quotePos, quote);
					didFlip = true;
				} else
					otherSeen = true;
			}
			if (rangeSafe && (c == '\\' || c == '[' || c == '(' || c == ']' || c == ')' || c == ',' || c <= ' '))
				sb.append('\\');
			sb.append(c);
		}
		sb.append(quote);
	}

	private static int compareSegments(Comparable a, Comparable b) {
		if (a == b)
			return 0;

		if (a instanceof Integer && b instanceof Integer) {
			int ai = ((Integer) a).intValue();
			int bi = ((Integer) b).intValue();
			return ai > bi ? 1 : (ai < bi ? -1 : 0);
		}

		if (a instanceof String && b instanceof String)
			return a.compareTo(b);

		if (a == MAX_VALUE || a == MIN_VALUE || a == MAXS_VALUE)
			return a.compareTo(b);

		if (b == MAX_VALUE || b == MIN_VALUE || b == MAXS_VALUE)
			return -b.compareTo(a);

		if (a instanceof Integer)
			return 1;
		if (b instanceof Integer)
			return -1;
		if (a instanceof VersionVector)
			return (b instanceof VersionVector) ? a.compareTo(b) : 1;

		if (b instanceof VersionVector)
			return -1;

		throw new IllegalArgumentException();
	}

	private Comparable padValue;

	private Comparable[] vector;

	VersionVector() {
		// Constructor used in conjunction with init (when version is parsed from string)
	}

	VersionVector(Comparable[] vector, Comparable pad) {
		this.vector = vector;
		this.padValue = (pad == MIN_VALUE) ? null : pad;
	}

	public int compareTo(Object o) {
		if (o == this)
			return 0;

		VersionVector ov = (VersionVector) o;
		Comparable[] t_vector = vector;
		Comparable[] o_vector = ov.vector;
		int top = t_vector.length;
		if (top > o_vector.length)
			top = o_vector.length;

		for (int idx = 0; idx < top; ++idx) {
			int cmp = compareSegments(t_vector[idx], o_vector[idx]);
			if (cmp != 0)
				return cmp;
		}

		// All elements compared equal up to this point. Check
		// pad values
		if (top < t_vector.length)
			return (ov.padValue == null) ? 1 : compareReminder(top, ov.padValue);

		if (top < o_vector.length)
			return (padValue == null) ? -1 : -ov.compareReminder(top, padValue);

		// Lengths are equal. Compare pad values
		return padValue == null ? (ov.padValue == null ? 0 : -1) : (ov.padValue == null ? 1 : compareSegments(padValue, ov.padValue));
	}

	public boolean equals(Object o) {
		if (o == this)
			return true;

		if (!(o instanceof VersionVector))
			return false;

		VersionVector ov = (VersionVector) o;

		// We compare pad first since it is impossible for versions with
		// different pad to be equal (versions are padded to infinity) 
		if (padValue == null) {
			if (ov.padValue != null)
				return false;
		} else {
			if (ov.padValue == null || !padValue.equals(ov.padValue))
				return false;
		}

		Comparable[] t_vector = vector;
		Comparable[] o_vector = ov.vector;
		int idx = t_vector.length;

		// If the length of the vector differs, the versions cannot be equal
		// since segments equal to pad are stripped by the parser
		if (idx != o_vector.length)
			return false;

		while (--idx >= 0)
			if (!t_vector[idx].equals(o_vector[idx]))
				return false;

		return true;
	}

	/**
	 * Returns the pad value used when comparing this versions to
	 * versions that has a raw vector with a larger number of elements
	 * @return The pad value or <code>null</code> if not set.
	 */
	public Comparable getPad() {
		return padValue;
	}

	/**
	 * An element from the raw vector
	 * @param index The zero based index of the desired element
	 * @return An element from the raw vector
	 */
	public Comparable getSegment(int index) {
		return vector[index];
	}

	/**
	 * Returns the number of elements in the raw vector
	 * @return The element count
	 */
	public int getSegmentCount() {
		return vector.length;
	}

	public int hashCode() {
		int hashCode = padValue == null ? 31 : padValue.hashCode();
		int idx = vector.length;
		while (--idx >= 0) {
			Object elem = vector[idx];
			if (elem != null)
				hashCode += elem.hashCode();
			hashCode = hashCode * 31;
		}
		return hashCode;
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		toString(sb);
		return sb.toString();
	}

	/**
	 * Append the string representation of this instance to the
	 * <code>sb</code> buffer.
	 * @param sb The buffer to append to
	 */
	public void toString(StringBuffer sb) {
		toString(sb, false);
	}

	/**
	 * Append the string representation of this instance to the
	 * <code>sb</code> buffer.
	 * @param sb The buffer to append to
	 * @param rangeSafe If <code>true</code>, the range delimiters will be escaped
	 * with backslash.
	 */
	public void toString(StringBuffer sb, boolean rangeSafe) {
		int top = vector.length;
		if (top == 0)
			// Write one pad value as explicit. It will be considered
			// redundant and removed by the parser but the raw format
			// does not allow zero elements
			rawToString(sb, rangeSafe, padValue == null ? MIN_VALUE : padValue);
		else {
			for (int idx = 0; idx < top; ++idx) {
				if (idx > 0)
					sb.append('.');
				rawToString(sb, rangeSafe, vector[idx]);
			}
		}
		if (padValue != null) {
			sb.append('p');
			rawToString(sb, rangeSafe, padValue);
		}
	}

	/**
	 * This method is package protected since it violates the immutable
	 * contract.
	 * @return The raw vector. Must be treated as read-only
	 */
	Comparable[] getVector() {
		return vector;
	}

	void init(Comparable[] vec, Comparable pad) {
		vector = vec;
		padValue = (pad == MIN_VALUE) ? null : pad;
	}

	private int compareReminder(int idx, Comparable othersPad) {
		int cmp;
		for (cmp = 0; idx < vector.length && cmp == 0; ++idx)
			cmp = compareSegments(vector[idx], othersPad);
		if (cmp == 0)
			cmp = (padValue == null) ? -1 : padValue.compareTo(othersPad);
		return cmp;
	}
}
