/*=============================================================================#
 # Copyright (c) 2009, 2022 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.internal.jcommons.runtime.eplatform;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Set;

import org.osgi.framework.Bundle;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;

import org.eclipse.statet.internal.jcommons.runtime.CommonsRuntimeInternals;
import org.eclipse.statet.jcommons.io.UriUtils;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.lang.ObjectUtils.ToStringBuilder;
import org.eclipse.statet.jcommons.runtime.bundle.BundleEntry;
import org.eclipse.statet.jcommons.runtime.bundle.BundleResolver;
import org.eclipse.statet.jcommons.runtime.bundle.BundleSpec;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.MultiStatus;


@NonNullByDefault
public class EPlatformBundleResolver implements BundleResolver {
	
	
	private static class OsgiJarBundleEntry extends BundleEntry.Jar {
		
		
		private final Bundle osgiBundle;
		
		
		public OsgiJarBundleEntry(final String bundleId, final Path path, final Bundle osgiBundle) {
			super(bundleId, path);
			this.osgiBundle= osgiBundle;
		}
		
		
		@Override
		public @Nullable String getResourceUrlString(final String resource) {
			final URL intern= this.osgiBundle.getEntry(resource);
			if (intern != null) {
				try {
					final URI url= UriUtils.toUri(FileLocator.resolve(intern));
					return url.toString();
				}
				catch (URISyntaxException | IOException e) {
				}
			}
			return super.getResourceUrlString(resource);
		}
		
	}
	
	private static class OsgiDirBundleEntry extends BundleEntry.Dir {
		
		
		private final Bundle osgiBundle;
		
		
		public OsgiDirBundleEntry(final String bundleId, final Path path, final Path jClassPath,
				final Bundle osgiBundle) {
			super(bundleId, path, jClassPath);
			this.osgiBundle= osgiBundle;
		}
		
		
		@Override
		public @Nullable String getResourceUrlString(final String resource) {
			final URL intern= this.osgiBundle.getEntry(resource);
			if (intern != null) {
				try {
					final URI url= UriUtils.toUri(FileLocator.resolve(intern));
					return url.toString();
				}
				catch (URISyntaxException | IOException e) {
				}
			}
			return super.getResourceUrlString(resource);
		}
		
	}
	
	
	public EPlatformBundleResolver() {
		if (Platform.getBundle(CommonsRuntimeInternals.BUNDLE_ID) == null) {
			throw new UnsupportedOperationException();
		}
	}
	
	
	@Override
	public boolean resolveBundle(final BundleSpec bundleSpec,
			final Set<BundleEntry> resolved, final MultiStatus status) {
		final Bundle pluginBundle= Platform.getBundle(bundleSpec.getId());
		if (pluginBundle != null) {
			final boolean ok= addEntries(pluginBundle, resolved, status);
			final @NonNull Bundle [] fragments= Platform.getFragments(pluginBundle);
			if (fragments != null) {
				for (final Bundle fragmentBundle : fragments) {
					addEntries(fragmentBundle, resolved, status);
				}
			}
			return ok;
		}
		return false;
	}
	
	private boolean addEntries(final Bundle bundle, final Set<BundleEntry> resolved,
			final MultiStatus status) {
//			String location= bundle.getLocation();
//			if (location.startsWith("initial@")) {
//				location= location.substring(8);
//			}
//			if (location.startsWith("reference:file:")) { //$NON-NLS-1$
//				location= location.substring(15);
//				IPath path= new Path(location);
//				if (!path.isAbsolute()) {
//					path= new Path(Platform.getInstallLocation().getURL().getFile()).append(path);
//				}
//				String checked= path.lastSegment();
//				if (checked.contains("motif")) { //$NON-NLS-1$
//					checked= checked.replaceAll("motif", "gtk"); //$NON-NLS-1$ //$NON-NLS-2$
//				}
//				if (checked.contains("gtk")) { //$NON-NLS-1$
//					if (is64 && !checked.contains("64")) { //$NON-NLS-1$
//						checked= checked.replaceAll("x86", "x86_64"); //$NON-NLS-1$ //$NON-NLS-2$
//					}
//					if (!is64 && checked.contains("64")) { //$NON-NLS-1$
//						checked= checked.replaceAll("x86_64", "x86"); //$NON-NLS-1$ //$NON-NLS-2$
//					}
//				}
//				final String s= path.removeLastSegments(1).append(checked).makeAbsolute().toOSString();
//				if (location.endsWith("/")) { // //$NON-NLS-1$
//					if (Platform.inDevelopmentMode()) {
//						classpath.add(s+File.separatorChar+"bin"+File.separatorChar); //$NON-NLS-1$
//					}
//					classpath.add(s+File.separatorChar);
//				}
//				else {
//					classpath.add(s);
//				}
//				return;
//			}
		try {
			final String libId= nonNullAssert(bundle.getSymbolicName());
			URI url= UriUtils.toUri(FileLocator.resolve(bundle.getEntry("/")));
			final boolean isJar= UriUtils.isJarUrl(url);
			if (isJar && UriUtils.getJarEntryPath(url).isEmpty()) {
				url= UriUtils.getJarFileUrl(url);
			}
			final Path path= Path.of(url);
			if (Platform.inDevelopmentMode() && !isJar) {
				final Path jClassPath;
				if (Files.isDirectory(jClassPath= path.resolve("target/classes"))) {
					resolved.add(new OsgiDirBundleEntry(libId, path, jClassPath, bundle));
					return true;
				}
			}
			resolved.add((isJar) ?
					new OsgiJarBundleEntry(libId, path, bundle) :
					new OsgiDirBundleEntry(libId, path, path, bundle));
			return true;
		}
		catch (final Exception e) {
			status.add(new ErrorStatus(CommonsRuntimeInternals.BUNDLE_ID,
					String.format("Failed to check location for plug-in: '%1$s'.", //$NON-NLS-1$
							bundle.getSymbolicName() ),
					e ));
			return false;
		}
	}
	
	
	@Override
	public String toString() {
		final ToStringBuilder sb= new ToStringBuilder("BundleResolver", getClass()); //$NON-NLS-1$
		return sb.toString();
	}
	
}
