/*=============================================================================#
 # Copyright (c) 2017, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rj.services;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.lang.ObjectUtils;


@NonNullByDefault
public class RVersion implements Comparable<RVersion> {
	
	private static int parseInt(final String value, final String componentName) {
		try {
			return Integer.parseInt(value);
		}
		catch (final NumberFormatException e) {
			throw new IllegalArgumentException(componentName + "= '" + value + "'", e);
		}
	}
	
	private static void validateInt(final int value, final String componentName) {
		if (value < 0) {
			throw new IllegalArgumentException(componentName + "= " + value);
		}
	}
	
	
	private final int major;
	private final int minor;
	private final int patch;
	private final String build;
	
	private transient @Nullable String versionString;
	private transient int hash;
	
	
	public RVersion(final int major, final int minor, final int micro,
			final @Nullable String qualifier) {
		this.major= major;
		this.minor= minor;
		this.patch= micro;
		this.build= ObjectUtils.nonNullElse(qualifier, ""); //$NON-NLS-1$
		validate();
	}
	
	public RVersion(final int major, final int minor, final int path) {
		this(major, minor, path, null);
	}
	
	public RVersion(final String version) {
		int major= 0;
		int minor= 0;
		int patch= 0;
		String build= "";
		{	final String[] components= version.split("\\.", 4);
			if (components.length == 0 || components[0].isEmpty()) {
				throw new IllegalArgumentException("version= '" +  version + "'");
			}
			major= parseInt(components[0], "major");
			if (components.length >= 2) {
				minor= parseInt(components[1], "minor");
				if (components.length >= 3) {
					patch= parseInt(components[2], "patch");
					if (components.length >= 4) {
						build= components[3];
					}
				}
			}
		}
		
		this.major= major;
		this.minor= minor;
		this.patch= patch;
		this.build= build;
		validate();
	}
	
	private void validate() {
		validateInt(this.major, "major");
		validateInt(this.minor, "minor");
		validateInt(this.patch, "patch");
		for (int i= 0; i < this.build.length(); i++) {
			final char c= this.build.charAt(i);
			if (!Character.isDefined(c) || c == ' ') {
				throw new IllegalArgumentException("build= " + this.build);
			}
		}
	}
	
	
	public int getMajor() {
		return this.major;
	}
	
	public int getMinor() {
		return this.minor;
	}
	
	public int getMicro() {
		return this.patch;
	}
	
	public String getBuild() {
		return this.build;
	}
	
	
	@Override
	public int hashCode() {
		int h= this.hash;
		if (h != 0) {
			return h;
		}
		h= 31 * 17;
		h= 31 * h + this.major;
		h= 31 * h + this.minor;
		h= 31 * h + this.patch;
		h= 31 * h + this.build.hashCode();
		return this.hash= h;
	}
	
	@Override
	public boolean equals(final @Nullable Object object) {
		if (this == object) {
			return true;
		}
		if (object instanceof RVersion) {
			final RVersion other= (RVersion) object;
			return ((this.major == other.major)
					&& (this.minor == other.minor)
					&& (this.patch == other.patch)
					&& this.build.equals(other.build) );
		}
		return false;
	}
	
	@Override
	public int compareTo(final RVersion other) {
		if (this == other) {
			return 0;
		}
		int result= this.major - other.major;
		if (result != 0) {
			return result;
		}
		result= this.minor - other.minor;
		if (result != 0) {
			return result;
		}
		result= this.patch - other.patch;
		if (result != 0) {
			return result;
		}
		return this.build.compareTo(other.build);
	}
	
	@Override
	public String toString() {
		final String s= this.versionString;
		if (s != null) {
			return s;
		}
		final StringBuilder result= new StringBuilder(20 + this.build.length());
		result.append(this.major);
		result.append('.');
		result.append(this.minor);
		result.append('.');
		result.append(this.patch);
		if (!this.build.isEmpty()) {
			result.append('.');
			result.append(this.build);
		}
		return this.versionString= result.toString();
	}
	
}
