/*=============================================================================#
 # Copyright (c) 2009, 2021 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.jcommons.rmi;

import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.Registry;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.net.Port;


/**
 * Address for RMI naming
 */
@NonNullByDefault
public class RMIAddress {
	
	
	public static void validate(final String address) throws MalformedURLException {
		try {
			new RMIAddress(address, false);
		}
		catch (final UnknownHostException e) {
		}
	}
	
	private static final int DEFAULT_PORT_NUM= Registry.REGISTRY_PORT;
	public static final Port DEFAULT_PORT= new Port(DEFAULT_PORT_NUM);
	
	public static final String REGISTRY_NAME= ""; //$NON-NLS-1$
	
	
	private static String checkChars(final String s) throws MalformedURLException {
		for (int i= 0; i < s.length(); i++) {
			final char c= s.charAt(i);
			if (c == '?' || c == '#' || c == '[' || c == ']' || c == '@'
					|| c == '!' || c == '$' || c == '&' || c == '\'' || c == '(' || c == ')'
					|| c == '*' || c == '+' || c == ',' || c == ';' || c == '='
					|| c == '"' || c == '\\') {
				throw new MalformedURLException("Character '" + c+"' is not allowed.");
			}
		}
		return s;
	}
	
	private static String checkNameChars(final String s) throws IllegalArgumentException {
		for (int i= 0; i < s.length(); i++) {
			final char c= s.charAt(i);
			if (c == '?' || c == '#' || c == '[' || c == ']' || c == '@'
					|| c == '!' || c == '$' || c == '&' || c == '\'' || c == '(' || c == ')'
					|| c == '*' || c == '+' || c == ',' || c == ';' || c == '='
					|| c == '"' || c == '\\') {
				throw new IllegalArgumentException("Character '" + c + "' is not allowed.");
			}
		}
		return s;
	}
	
	private static Port parsePort(final String port) throws MalformedURLException {
		try {
			return Port.valueOf(port);
		}
		catch (final IllegalArgumentException e) {
			throw new MalformedURLException("Invalid port: " + e.getLocalizedMessage());
		}
	}
	
	private static Port checkPort(final Port port) {
		return (port.get() == DEFAULT_PORT_NUM) ? DEFAULT_PORT : port;
	}
	
	
	private static String build(final @Nullable String host, final int portNum,
			final @Nullable String name) {
		final StringBuilder sb= new StringBuilder("//"); //$NON-NLS-1$
		if (host != null) {
			sb.append(host);
		}
		sb.append(':');
		if (portNum >= 0) {
			sb.append(Integer.toString(portNum));
		}
		sb.append('/');
		if (name != null) {
			sb.append(name);
		}
		return sb.toString();
	}
	
	
	private final @Nullable String host;
	private InetAddress hostAddress;
	private final Port port;
	private final boolean isSsl;
	private final String path;
	
	private @Nullable String address;
	private @Nullable String ser;
	
	
	public RMIAddress(final String address)
			throws UnknownHostException, MalformedURLException {
		this(address, true);
	}
	
	public RMIAddress(final @Nullable String host, final int portNum,
			final @Nullable String name)
			throws UnknownHostException, MalformedURLException {
		this(build(host, portNum, name), true);
	}
	
	public RMIAddress(final InetAddress address, final int portNum,
			final @Nullable String name)
			throws MalformedURLException {
		this(address.getHostAddress(), address, parsePort(Integer.toString(portNum)), false,
				(name != null) ? checkChars(name) : "" );
	}
	
	public RMIAddress(final InetAddress address, final Port port, final boolean isSsl,
			final String name) {
		this(address.getHostAddress(), address, checkPort(port), isSsl,
				checkNameChars(name) );
	}
	
	public RMIAddress(final InetAddress address, final Port port,
			final String name) {
		this(address.getHostAddress(), address, checkPort(port), false,
				checkNameChars(name) );
	}
	
	public RMIAddress(final RMIAddress registry,
			final String name) {
		this(registry.host, registry.hostAddress, registry.port, registry.isSsl,
				checkNameChars(name) );
	}
	
	private RMIAddress(String address, final boolean resolve)
			throws UnknownHostException, MalformedURLException {
		address= checkChars(address);
		
		if (address.startsWith("ssl:")) { //$NON-NLS-1$
			address= address.substring(4);
			this.isSsl= true;
		}
		else {
			this.isSsl= false;
		}
		if (address.startsWith("rmi:")) { //$NON-NLS-1$
			address= address.substring(4);
		}
		if (!address.startsWith("//")) { //$NON-NLS-1$
			address= "//"+address; //$NON-NLS-1$
		}
		
		final int idxPort= address.indexOf(':', 2);
		final int idxPath= address.indexOf('/', 2);
		if (idxPort > 0) {
			if (idxPath <= idxPort) {
				throw new IllegalArgumentException();
			}
			this.host= (2 < idxPort) ? address.substring(2, idxPort) : null;
			this.port= (idxPort + 1 < idxPath) ?
					checkPort(parsePort(address.substring(idxPort + 1, idxPath))) :
					DEFAULT_PORT;
			this.path= address.substring(idxPath+1);
		}
		else if (idxPath > 0){
			this.host= (2 < idxPath) ? address.substring(2, idxPath) : null;
			this.port= DEFAULT_PORT;
			this.path= address.substring(idxPath+1);
		}
		else {
			this.host= null;
			this.port= DEFAULT_PORT;
			this.path= address.substring(2);
		}
		if (resolve) {
			this.hostAddress= (this.host != null) ? InetAddress.getByName(this.host) : InetAddress.getLoopbackAddress();
		}
	}
	
	private RMIAddress(final @Nullable String host, final InetAddress hostAddress, final Port port,
			final boolean isSsl, final String path) {
		this.host= host;
		this.hostAddress= hostAddress;
		this.port= port;
		this.isSsl= isSsl;
		this.path= path;
	}
	
	
	/**
	 * @return the host as specified when creating the address
	 */
	public String getHost() {
		return (this.host != null) ? this.host : this.hostAddress.getHostAddress();
	}
	
	public InetAddress getHostAddress() {
		return this.hostAddress;
	}
	
	public boolean isLocalHost() {
		if (this.hostAddress.isLoopbackAddress()) {
			return true;
		}
		try {
			final InetAddress localhost= InetAddress.getLocalHost();
			if (this.hostAddress.equals(localhost)) {
				return true;
			}
		}
		catch (final UnknownHostException e) {}
		catch (final ArrayIndexOutOfBoundsException e) { /* JVM bug */ }
		
		return false;
	}
	
	public Port getPort() {
		return this.port;
	}
	
	/**
	 * @return the name
	 */
	public String getName() {
		return this.path;
	}
	
	/**
	 * Standard string presentation to use for rmi
	 * @return
	 */
	public String getAddress() {
		String address= this.address;
		if (address == null) {
			final StringBuilder sb= new StringBuilder(32);
			sb.append("rmi://"); //$NON-NLS-1$
			if (this.host != null) {
				sb.append(this.host);
			}
			if (this.port != DEFAULT_PORT) {
				sb.append(':');
				sb.append(this.port);
			}
			sb.append('/');
			sb.append(this.path);
			address= sb.toString();
			this.address= address;
		}
		return address;
	}
	
	public RMIAddress getRegistryAddress() {
		return new RMIAddress(this.host, this.hostAddress, this.port, this.isSsl, "");
	}
	
	public Remote lookup() throws RemoteException, NotBoundException, AccessException {
		final RMIRegistry rmiRegistry= new RMIRegistry(getRegistryAddress(), false);
		return rmiRegistry.getRegistry().lookup(getName());
	}
	
	/**
	 * 
	 * @return if SSL is enabled
	 * 
	 * @since 1.4
	 */
	public boolean isSsl() {
		return this.isSsl;
	}
	
	
	@Override
	public String toString() {
		String ser= this.ser;
		if (ser == null) {
			if (this.isSsl) {
				ser= "ssl:" + getAddress();
			}
			else {
				ser= getAddress();
			}
			this.ser= ser;
		}
		return ser;
	}
	
	@Override
	public int hashCode() {
		return toString().hashCode();
	}
	
	@Override
	public boolean equals(final @Nullable Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof RMIAddress) {
			final RMIAddress other= (RMIAddress) obj;
			return (this.hostAddress.equals(other.hostAddress)
					&& this.port.equals(other.port)
					&& this.isSsl == other.isSsl
					&& this.path.equals(other.path) );
		}
		return false;
	}
	
}
