/*=============================================================================#
 # Copyright (c) 2018, 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.io;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

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


@NonNullByDefault
public class UriUtils {
	
	
	public static final String HTTP_SCHEME= "http"; //$NON-NLS-1$
	public static final String HTTPS_SCHEME= "https"; //$NON-NLS-1$
	public static final String FILE_SCHEME= "file"; //$NON-NLS-1$
	public static final String JAR_SCHEME= "jar"; //$NON-NLS-1$
	
	public static final String JAR_SEPARATOR = "!/"; //$NON-NLS-1$
	
	
	public static final URI toUri(final URL url) throws URISyntaxException {
		final String s= url.toExternalForm();
		final String scheme= url.getProtocol();
		final String fragment= url.getRef();
		final String spp= s.substring(scheme.length() + 1,
				(fragment != null) ? s.length() - fragment.length() - 1 : s.length() );
		return new URI(scheme, spp, fragment);
	}
	
	
	private static boolean isScheme(final @Nullable String scheme, final String expectedScheme) {
		final int n= expectedScheme.length();
		if (scheme == null || scheme.length() != n) {
			return false;
		}
		for (int index= 0; index < n; index++) {
			final char c= scheme.charAt(index);
			final char cExpected= expectedScheme.charAt(index);
			if (c != cExpected && Character.toLowerCase(c) != cExpected) {
				return false;
			}
		}
		return true;
	}
	
	private static boolean isSchemeUrl(final String urlString, final String expectedScheme) {
		final int n= expectedScheme.length();
		if (urlString.length() <= n || urlString.charAt(n) != ':') {
			return false;
		}
		for (int index= 0; index < n; index++) {
			final char c= urlString.charAt(index);
			final char cExpected= expectedScheme.charAt(index);
			if (c != cExpected && Character.toLowerCase(c) != cExpected) {
				return false;
			}
		}
		return true;
	}
	
	/**
	 * Returns if the specified URL is a file URL.
	 * 
	 * <p>The function does not validate the URL.</p>
	 * 
	 * @param url the URL
	 * @return <code>true</code> if it is a file URL, otherwise <code>false</code>
	 */
	public static final boolean isFileUrl(final URI url) {
		return isScheme(url.getScheme(), FILE_SCHEME);
	}
	
	/**
	 * Returns if the specified URL is a file URL.
	 * 
	 * <p>The function does not validate the URL.</p>
	 * 
	 * @param urlString the URL
	 * @return <code>true</code> if it is a file URL, otherwise <code>false</code>
	 */
	public static final boolean isFileUrl(final String urlString) {
		return isSchemeUrl(urlString, FILE_SCHEME);
	}
	
	/**
	 * Returns if the specified URL is a JAR URL.
	 * 
	 * <p>The function does not validate the URL.</p>
	 * 
	 * @param url the URL
	 * @return <code>true</code> if it is a JAR URL, otherwise <code>false</code>
	 */
	public static final boolean isJarUrl(final URI url) {
		return isScheme(url.getScheme(), JAR_SCHEME);
	}
	
	private static URI assertJarUrlArgument(final URI url) {
		if (!isJarUrl(url)) {
			throw new IllegalArgumentException("no JAR url");
		}
		return url;
	}
	
	/**
	 * Returns if the specified URL is a JAR URL.
	 * 
	 * <p>The function does not validate the URL.</p>
	 * 
	 * @param urlString the URL
	 * @return <code>true</code> if it is a JAR URL, otherwise <code>false</code>
	 */
	public static final boolean isJarUrl(final String urlString) {
		return isSchemeUrl(urlString, JAR_SCHEME);
	}
	
	/**
	 * Return the URL of the JAR archive file.
	 * 
	 * @param url the JAR URL
	 * @return the URL of the archive file
	 * @throws IllegalArgumentException if the specified URL is not a JAR URL
	 * @throws URISyntaxException if the specified URL is invalid
	 * 
	 * @see {@link #getJarEntryPath(URI)} for the other part of the URL
	 */
	public static final URI getJarFileUrl(final URI url) throws URISyntaxException {
		assertJarUrlArgument(url);
		final String ssp= url.getSchemeSpecificPart();
		final int containerSchemeIdx= ssp.indexOf(':');
		if (containerSchemeIdx <= 0) {
			throw new URISyntaxException(url.toString(), "missing container scheme");
		}
		final int jarSepIdx= ssp.lastIndexOf(JAR_SEPARATOR);
		if (jarSepIdx < containerSchemeIdx) {
			throw new URISyntaxException(url.toString(), "missing JAR separator");
		}
		return (ssp.lastIndexOf(JAR_SEPARATOR, jarSepIdx - 1) == -1) ?
				// remove jar scheme
				new URI(ssp.substring(0, containerSchemeIdx),
						ssp.substring(containerSchemeIdx + 1, jarSepIdx),
						url.getFragment() ) :
				// nested jar
				new URI(url.getScheme(),
						ssp.substring(0, jarSepIdx),
						url.getFragment() );
	}
	
	/**
	 * Return the path of the entry inside the JAR archive.
	 * 
	 * @param url the JAR URL
	 * @return the path of the entry as String (without leading slash)
	 * @throws IllegalArgumentException if the specified URL is not a JAR URL
	 * @throws URISyntaxException if the specified URL is invalid
	 * 
	 * @see {@link #getJarFileUrl(URI)} for the other part of the URL
	 */
	public static final String getJarEntryPath(final URI url) throws URISyntaxException {
		assertJarUrlArgument(url);
		final String ssp= url.getSchemeSpecificPart();
		final int containerSchemeIdx= ssp.indexOf(':');
		if (containerSchemeIdx <= 0) {
			throw new URISyntaxException(url.toString(), "missing container scheme");
		}
		final int jarSepIdx= ssp.lastIndexOf(JAR_SEPARATOR);
		if (jarSepIdx < containerSchemeIdx) {
			throw new URISyntaxException(url.toString(), "missing JAR separator");
		}
		return ssp.substring(jarSepIdx + 2, ssp.length());
	}
	
	/**
	 * Returns the JAR URL pointing to the root inside the specified JAR file.
	 * 
	 * @param jarFileUrlString URL as String pointing to the JAR file itself
	 * @return the JAR URL as String
	 * @throws URISyntaxException
	 */
	public static final URI toJarUrl(final String jarFileUrlString) throws URISyntaxException {
		return new URI(toJarUrlString(jarFileUrlString));
	}
	
	/**
	 * Returns the JAR URL as String pointing to the root inside the specified JAR file.
	 * 
	 * @param jarFileUrlString URL as String pointing to the JAR file itself
	 * @return the JAR URL as String
	 * @throws URISyntaxException
	 */
	public static final String toJarUrlString(final String jarFileUrlString) throws URISyntaxException {
		final StringBuilder sb= new StringBuilder(jarFileUrlString.length() + 6);
		if (!isSchemeUrl(jarFileUrlString, JAR_SCHEME)) {
			sb.append(UriUtils.JAR_SCHEME + ':');
		}
		sb.append(jarFileUrlString);
		sb.append(UriUtils.JAR_SEPARATOR);
		return sb.toString();
	}
	
	
	private UriUtils() {
	}
	
}
