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

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
import static org.eclipse.statet.jcommons.runtime.CommonsRuntime.log;

import java.io.Closeable;
import java.io.IOException;
import java.net.URI;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemAlreadyExistsException;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.runtime.ClassLoaderUtils;
import org.eclipse.statet.jcommons.runtime.UriUtils;
import org.eclipse.statet.jcommons.status.ErrorStatus;

import org.eclipse.statet.rj.RjInitFailedException;


@NonNullByDefault
public abstract class PathEntryProvider {
	
	
	public static class JarFilePathEntryProvider extends PathEntryProvider {
		
		
		private final Pattern namePattern;
		
		
		public JarFilePathEntryProvider(final ImList<Path> baseDirectories, final Pattern namePattern,
				final List<Closeable> closeables) {
			super(baseDirectories, closeables);
			this.namePattern= namePattern;
		}
		
		
		@Override
		public void getEntries(final Path baseDirectory, final List<PathEntry> entries)
				throws IOException {
			try (final DirectoryStream<Path> children= Files.newDirectoryStream(baseDirectory)) {
				for (final Path child : children) {
					final Matcher nameMatcher= this.namePattern.matcher(child.getFileName().toString());
					if (nameMatcher.matches() && Files.isRegularFile(child)) {
						final String bundleId= nonNullAssert(nameMatcher.group(1));
						entries.add(new PathEntry.Jar(bundleId, child));
					}
				}
			}
		}
		
	}
	
	public static class DevBinPathEntryProvider extends PathEntryProvider {
		
		
		public DevBinPathEntryProvider(final ImList<Path> baseDirectories,
				final List<Closeable> closeables) {
			super(baseDirectories, closeables);
		}
		
		
		@Override
		public void getEntries(final Path baseDirectory, final List<PathEntry> entries)
				throws IOException {
			try (final DirectoryStream<Path> children= Files.newDirectoryStream(baseDirectory)) {
				for (final Path child : children) {
					final Path devBin;
					if (Files.isDirectory(devBin= child.resolve("bin"))) {
						final String bundleId= child.getFileName().toString();
						entries.add(new PathEntry(bundleId, devBin) {
							@Override
							public @Nullable Path getResourcePath(final String resource) {
								Path path= super.getResourcePath(resource);
								if (path != null) {
									return path;
								}
								path= getPath().resolveSibling(resource);
								if (Files.exists(path)) {
									return path;
								}
								return null;
							}
						});
					}
				}
			}
		}
		
	}
	
	
	// Pattern to detect:
//	file:/../org.eclipse.statet-rj/core/org.eclipse.statet.rj.server/bin/
//	jar:file:/../org.eclipse.statet-rj/core/org.eclipse.statet.rj.server/target/org.eclipse.statet.rj.server-3.0.0-SNAPSHOT.jar!/
//	jar:file:/../rserver/org.eclipse.statet.rj.server.jar!/
//	jar:file:/../rhelp.server-4.0.0-SNAPSHOT.jar!/BOOT-INF/lib/org.eclipse.statet.rj.server-3.0.0-SNAPSHOT.jar!/
	private static final String FILE_PROTOCOL_REGEX= "\\Qfile:/\\E";
	private static final String JAR_FILE_PROTOCOL_REGEX= "\\Qjar:file:/\\E";
	private static final String SERVER_BUNDLE_ID_REGEX= "\\Q" + ServerUtils.RJ_SERVER_ID + "\\E";
	private static final String VER_1_REGEX= "\\_\\d+\\.\\d+[^!/]+";
	private static final String VER_2_REGEX= "\\-\\d+\\.\\d+[^!/]+";
	private static final String JAR_REGEX= "\\Q.jar\\E";
	private static final String AUTODETECT_REGEX=
			"(?:" +
				"(" + FILE_PROTOCOL_REGEX + ".*)/" + SERVER_BUNDLE_ID_REGEX + "\\Q/bin/\\E" + // match 1= file: ..
			"|" +
				"(" + JAR_FILE_PROTOCOL_REGEX + ".*)/" + SERVER_BUNDLE_ID_REGEX + // match 2= jar:file: ..
						"(?:(" + VER_1_REGEX + ")|(" + VER_2_REGEX + "))?" + // match 3= ver_1, match 4= ver_2
						JAR_REGEX + "\\Q!/\\E" +
			")";
	
	private static final Pattern AUTODETECT_PATTERN= Pattern.compile(AUTODETECT_REGEX);
	private static final Pattern JAR_VER_0_PATTERN= Pattern.compile("(.+)" + JAR_REGEX); //$NON-NLS-1$
	private static final Pattern JAR_VER_1_PATTERN= Pattern.compile("(.+)" + VER_1_REGEX + JAR_REGEX); //$NON-NLS-1$
	private static final Pattern JAR_VER_2_PATTERN= Pattern.compile("(.+)" + VER_2_REGEX + JAR_REGEX); //$NON-NLS-1$
	
	public static PathEntryProvider detectLibPaths(final Class<?> refClass,
			final @Nullable List<Path> expliciteBaseDirectories) throws RjInitFailedException {
		String refUrl= null;
		List<Closeable> closeables= ImCollections.emptyList();
		try {
			refUrl= ClassLoaderUtils.getClassLocationUrlString(refClass);
			final Matcher matcher= AUTODETECT_PATTERN.matcher(refUrl);
			if (matcher.matches()) {
				int detectedType;
				final URI detectedBaseUri;
				if (matcher.start(1) != -1) { // file:
					detectedType= 1;
					final String s= nonNullAssert(matcher.group(1));
					detectedBaseUri= new URI(s);
				}
				else if (matcher.start(2) != -1) { // jar:file:
					detectedType= 2;
					final String s= nonNullAssert(matcher.group(2));
					if (s.indexOf(UriUtils.JAR_SEPARATOR) == -1) {
						detectedBaseUri= new URI(s.substring(4)); // remove jar
					}
					else {
						detectedBaseUri= new URI(s);
					}
				}
				else {
					throw new IllegalStateException();
				}
				
				final ImList<Path> baseDirectories;
				{	Path detectedBaseDirectory;
					while (true) {
						try {
							detectedBaseDirectory= Paths.get(detectedBaseUri);
							break;
						}
						catch (final FileSystemNotFoundException e) {
							final Map<String, String> fsEnv= new HashMap<>();
							fsEnv.put("create", "true");
							try {
								final FileSystem fs= FileSystems.newFileSystem(detectedBaseUri, fsEnv);
		//						closeables= ImCollections.newList(fs);
							}
							catch (final FileSystemAlreadyExistsException exists) {}
						}
					}
					detectedBaseDirectory= detectedBaseDirectory.normalize();
					
					if (expliciteBaseDirectories != null && !expliciteBaseDirectories.isEmpty()) {
						final List<Path> uniqueList= new ArrayList<>();
						for (Path baseDirectory : expliciteBaseDirectories) {
							baseDirectory= baseDirectory.normalize();
							if (!uniqueList.contains(baseDirectory)) {
								uniqueList.add(baseDirectory);
							}
						}
						if (!uniqueList.contains(detectedBaseDirectory)) {
							uniqueList.add(detectedBaseDirectory);
						}
						baseDirectories= ImCollections.toList(uniqueList);
					}
					else {
						baseDirectories= ImCollections.newList(detectedBaseDirectory);
					}
				}
				
				final PathEntryProvider provider;
				if (detectedType == 1) {
					provider= new DevBinPathEntryProvider(baseDirectories,
							closeables );
				}
				else {
					final Pattern fileNamePattern;
					if (matcher.start(3) != -1) {
						fileNamePattern= JAR_VER_1_PATTERN;
					}
					else if (matcher.start(4) != -1) {
						fileNamePattern= JAR_VER_2_PATTERN;
					}
					else {
						fileNamePattern= JAR_VER_0_PATTERN;
					}
					provider= new JarFilePathEntryProvider(baseDirectories, fileNamePattern,
							closeables );
				}
				closeables= null;
				return provider;
			}
			throw new UnsupportedOperationException("url= " + refUrl);
		}
		catch (final Exception e) {
			throw new RjInitFailedException(
					String.format("Failed to autodetect RJ library location" +
							"\n\tclass= %1$s" + //$NON-NLS-1$
							"\n\turl= %2$s", //$NON-NLS-1$
							(refClass != null) ? refClass.getName() : "<NA>",
							(refUrl != null) ? '\'' + refUrl + '\'' : "<NA>" ),
					e );
		}
		finally {
			if (closeables != null) {
				close(closeables);
			}
		}
	}
	
	private static void close(final List<Closeable> closeables) {
		for (final Closeable closeable : closeables) {
			try {
				closeable.close();
			}
			catch (final Exception e) {
				log(new ErrorStatus(ServerUtils.RJ_SERVER_ID,
						"An error occurred when disposing closable of path entry provider.",
						e ));
			}
		}
	}
	
	
	private final ImList<Path> baseDirectories;
	
	private final List<Closeable> closeables;
	
	
	protected PathEntryProvider(final ImList<Path> baseDirectories,
			final List<Closeable> closeables) {
		this.baseDirectories= baseDirectories;
		this.closeables= closeables;
	}
	
	public void dispose() {
		close(this.closeables);
	}
	
	
	protected ImList<Path> getBaseDirectories() {
		return this.baseDirectories;
	}
	
	public void getEntries(final List<PathEntry> entries) {
		for (final Path baseDirectory : this.baseDirectories) {
			try {
				getEntries(baseDirectory, entries);
			}
			catch (final Exception e) {
				log(new ErrorStatus(ServerUtils.RJ_SERVER_ID,
						String.format("An error occurred when looking for path entries in '%1$s'.",
								baseDirectory ),
						e ));
			}
		}
	}
	
	protected abstract void getEntries(final Path baseDirectory, final List<PathEntry> entries)
			throws IOException;
	
}
