/*******************************************************************************
 * Copyright (c) 2008, 2020 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Christoph Läubrich - Bug 568865 - [target] add advanced editing capabilities for custom target platforms
 *******************************************************************************/
package org.eclipse.pde.internal.core.target;

import static java.util.Arrays.stream;
import static java.util.Collections.emptyList;
import static java.util.stream.Stream.concat;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.equinox.frameworkadmin.BundleInfo;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.core.target.ITargetDefinition;
import org.eclipse.pde.core.target.TargetBundle;
import org.eclipse.pde.core.target.TargetFeature;
import org.eclipse.pde.internal.core.P2Utils;
import org.eclipse.pde.internal.core.PDECore;

/**
 * A bundle container representing an installed profile.
 *
 * @since 3.5
 */
public class ProfileBundleContainer extends AbstractBundleContainer {

	// The following constants are duplicated from org.eclipse.equinox.internal.p2.core.Activator
	private static final String CONFIG_INI = "config.ini"; //$NON-NLS-1$
	private static final String PROP_AGENT_DATA_AREA = "eclipse.p2.data.area"; //$NON-NLS-1$
	private static final String PROP_PROFILE = "eclipse.p2.profile"; //$NON-NLS-1$
	private static final String PROP_CONFIG_DIR = "osgi.configuration.area"; //$NON-NLS-1$
	private static final String PROP_USER_DIR = "user.dir"; //$NON-NLS-1$
	private static final String PROP_USER_HOME = "user.home"; //$NON-NLS-1$
	private static final String VAR_CONFIG_DIR = "@config.dir"; //$NON-NLS-1$
	private static final String VAR_USER_DIR = "@user.dir"; //$NON-NLS-1$
	private static final String VAR_USER_HOME = "@user.home"; //$NON-NLS-1$

	/**
	 * Constant describing the type of bundle container
	 */
	public static final String TYPE = "Profile"; //$NON-NLS-1$

	/**
	 * Path to home/root install location. May contain string variables.
	 */
	private final String fHome;

	/**
	 * Alternate configuration location or <code>null</code> if default.
	 * May contain string variables.
	 */
	private final String fConfiguration;

	/**
	 * Creates a new bundle container for the profile at the specified location.
	 *
	 * @param home path in local file system, may contain string variables
	 * @param configurationLocation alternate configuration location or <code>null</code> for default,
	 *  may contain string variables
	 */
	public ProfileBundleContainer(String home, String configurationLocation) {
		fHome = home;
		fConfiguration = configurationLocation;
	}

	@Override
	public String getLocation(boolean resolve) throws CoreException {
		if (resolve) {
			return resolveHomeLocation().toOSString();
		}
		return fHome;
	}

	@Override
	public String getType() {
		return TYPE;
	}

	/**
	 * Returns the configuration area for this container if one was specified during creation.
	 *
	 * @return string path to configuration location or <code>null</code>
	 */
	public String getConfigurationLocation() {
		return fConfiguration;
	}

	@Override
	protected TargetBundle[] resolveBundles(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException {
		String home = resolveHomeLocation().toOSString();
		if (!new File(home).isDirectory()) {
			throw new CoreException(Status.error(NLS.bind(Messages.ProfileBundleContainer_0, home)));
		}

		File configurationArea = getConfigurationArea();
		if (configurationArea != null) {
			if (!configurationArea.isDirectory()) {
				throw new CoreException(Status.error(NLS.bind(Messages.ProfileBundleContainer_2, home)));
			}
		}

		BundleInfo[] infos = P2Utils.readBundles(home, configurationArea);
		if (infos == null) {
			if (configurationArea != null) {
				Collection<TargetBundle> osgiBundles = readBundleInfosFromConfigIni(configurationArea, new File(home));
				if (!osgiBundles.isEmpty()) {
					return osgiBundles.toArray(new TargetBundle[0]);
				}
			}
			DirectoryBundleContainer directoryBundleContainer = new DirectoryBundleContainer(home);
			directoryBundleContainer.resolve(definition, monitor);
			TargetBundle[] platformBundles = directoryBundleContainer.getBundles();
			if (platformBundles != null) {
				return platformBundles;
			}
			infos = new BundleInfo[0];
		}

		if (monitor.isCanceled()) {
			return new TargetBundle[0];
		}

		BundleInfo[] source = P2Utils.readSourceBundles(home, configurationArea);
		if (source == null) {
			source = new BundleInfo[0];
		}
		SubMonitor localMonitor = SubMonitor.convert(monitor, Messages.DirectoryBundleContainer_0, infos.length + source.length);

		return concat(stream(infos), stream(source)).parallel().map(info -> {
			URI location = info.getLocation();
			try {
				if (monitor.isCanceled()) {
					return null;
				}
				return new TargetBundle(URIUtil.toFile(location));
			} catch (CoreException e) {
				return new InvalidTargetBundle(new BundleInfo(location), e.getStatus());
			} finally {
				localMonitor.split(1);
			}
		}).filter(Objects::nonNull).toArray(TargetBundle[]::new);
	}

	private Collection<TargetBundle> readBundleInfosFromConfigIni(File configArea, File home) {
		File configIni = new File(configArea, CONFIG_INI);
		if (!configIni.isFile()) {
			return emptyList();
		}
		Properties configProps = new Properties();
		try (FileInputStream fis = new FileInputStream(configIni)) {
			configProps.load(fis);
		} catch (IOException e) {
			PDECore.log(e);
			return emptyList();
		}

		List<File> bundleFiles = parseBundlesFromConfigIni(configProps, home);
		ArrayList<TargetBundle> bundles = new ArrayList<>();
		for (File file : bundleFiles) {
			if (!file.exists()) {
				continue;
			}
			TargetBundle bundle;
			try {
				bundle = new TargetBundle(file);
			} catch (CoreException e) {
				bundle = new InvalidTargetBundle(new BundleInfo(file.toURI()), e.getStatus());
			}
			bundles.add(bundle);
		}
		return bundles;
	}

	public static List<File> parseBundlesFromConfigIni(Properties configProps, File home) {
		String osgiBundles = configProps.getProperty("osgi.bundles"); //$NON-NLS-1$
		if (osgiBundles == null || osgiBundles.isEmpty()) {
			return emptyList();
		}

		ArrayList<File> bundles = new ArrayList<>();
		File baseDir = null;

		String osgiFramework = configProps.getProperty("osgi.framework"); //$NON-NLS-1$
		if (osgiFramework != null) {
			File frameworkBundle = parseBundleLocation(osgiFramework);
			if (!frameworkBundle.isAbsolute()) {
				frameworkBundle = new File(home, frameworkBundle.getPath());
			}
			bundles.add(frameworkBundle);
			baseDir = frameworkBundle.getParentFile();
		}

		for (String spec : osgiBundles.split(",")) { //$NON-NLS-1$
			File location = parseBundleLocation(spec);
			if (baseDir == null || location.isAbsolute()) {
				bundles.add(location);
			} else {
				bundles.add(new File(baseDir, location.getPath()));
			}
		}

		return bundles;
	}

	private static File parseBundleLocation(String spec) {
		String path = spec.split("@", 2)[0]; //$NON-NLS-1$
		path = trimPrefix(path, "reference:"); //$NON-NLS-1$
		path = trimPrefix(path, "file:"); //$NON-NLS-1$
		return new File(path);
	}

	private static String trimPrefix(String string, String prefix) {
		if (string.startsWith(prefix)) {
			return string.substring(prefix.length());
		}

		return string;
	}

	@Override
	protected TargetFeature[] resolveFeatures(ITargetDefinition definition, IProgressMonitor monitor) throws CoreException {
		if (definition instanceof TargetDefinition) {
			return ((TargetDefinition) definition).resolveFeatures(getLocation(false), monitor);
		}
		return new TargetFeature[0];
	}

	/**
	 * Returns the home location with all variables resolved as a path.
	 *
	 * @return resolved home location
	 * @throws CoreException
	 */
	private IPath resolveHomeLocation() throws CoreException {
		return new Path(resolveVariables(fHome));
	}

	/**
	 * Returns a URL to the configuration area associated with this profile or <code>null</code>
	 * if none.
	 *
	 * @return configuration area URL or <code>null</code>
	 * @throws CoreException if unable to generate a URL or the user specified location does not exist
	 */
	private File getConfigurationArea() throws CoreException {
		IPath home = resolveHomeLocation();
		IPath configuration = null;
		if (fConfiguration == null) {
			configuration = home.append("configuration"); //$NON-NLS-1$
		} else {
			configuration = new Path(resolveVariables(fConfiguration));
		}
		File file = configuration.toFile();
		if (file.exists()) {
			return file;
		} else if (fConfiguration != null) {
			// If the user specified config area does not exist throw an error
			throw new CoreException(
					Status.error(NLS.bind(Messages.ProfileBundleContainer_2, configuration.toOSString())));
		}
		return null;
	}

	@Override
	public boolean equals(Object o) {
		if (o instanceof ProfileBundleContainer) {
			ProfileBundleContainer pbc = (ProfileBundleContainer) o;
			return fHome.equals(pbc.fHome) && isNullOrEqual(pbc.fConfiguration, fConfiguration);
		}
		return false;
	}

	@Override
	public int hashCode() {
		int hash = fHome.hashCode();
		if (fConfiguration != null) {
			hash += fConfiguration.hashCode();
		}
		return hash;
	}

	/**
	 * Returns the location of the profile file that describes the installation this container represents or <code>null</code>
	 * if no profile file could be determined.  This method checks the configuration file for a p2 data area entry and profile name
	 * to determine where the profile is located.
	 * <p>
	 * Note that when self hosting, the returned profile location will not have all running plug-ins installed unless the launch has generated
	 * a complete profile.
	 * </p>
	 *
	 * @return the profile file or <code>null</code>
	 */
	public File getProfileFileLocation() throws CoreException {
		// Get the configuration location
		String home = resolveHomeLocation().toOSString();
		if (!new File(home).isDirectory()) {
			throw new CoreException(Status.error(NLS.bind(Messages.ProfileBundleContainer_0, home)));
		}
		File configArea = getConfigurationArea();
		if (configArea == null) {
			configArea = new File(home);
		}
		if (!configArea.isDirectory()) {
			throw new CoreException(Status.error(NLS.bind(Messages.ProfileBundleContainer_2, configArea)));
		}

		// Location of the profile
		File p2DataArea = null;
		String profileName = null;

		// Load the config.ini to try and find the backing profile
		File configIni = new File(configArea, CONFIG_INI);
		if (configIni.isFile()) {
			// Read config.ini
			Properties configProps = new Properties();
			try (FileInputStream fis = new FileInputStream(configIni)) {
				configProps.load(fis);
			} catch (IOException e) {
				PDECore.log(e);
			}

			String p2Area = configProps.getProperty(PROP_AGENT_DATA_AREA);
			if (p2Area != null) {
				if (p2Area.startsWith(VAR_USER_HOME)) {
					String base = substituteVar(configProps, p2Area, VAR_USER_HOME, PROP_USER_HOME, configArea);
					p2Area = new Path(base).toFile().getAbsolutePath();
				} else if (p2Area.startsWith(VAR_USER_DIR)) {
					String base = substituteVar(configProps, p2Area, VAR_USER_DIR, PROP_USER_DIR, configArea);
					p2Area = new Path(base).toFile().getAbsolutePath();
				} else if (p2Area.startsWith(VAR_CONFIG_DIR)) {
					String base = substituteVar(configProps, p2Area, VAR_CONFIG_DIR, PROP_CONFIG_DIR, configArea);
					p2Area = new Path(base).toFile().getAbsolutePath();
				}
				p2DataArea = new File(p2Area);
			}

			profileName = configProps.getProperty(PROP_PROFILE);
		}

		if (p2DataArea == null || !p2DataArea.isDirectory()) {
			p2DataArea = new File(configArea, "p2"); //$NON-NLS-1$
		}

		if (profileName == null || profileName.length() == 0) {
			profileName = "SDKProfile"; //$NON-NLS-1$
		}

		@SuppressWarnings("restriction")
		File profile = new Path(p2DataArea.getAbsolutePath())
				.append(org.eclipse.equinox.internal.p2.engine.EngineActivator.ID).append("profileRegistry") //$NON-NLS-1$
				.append(profileName + ".profile").toFile(); //$NON-NLS-1$

		if (profile.exists()) {
			return profile;
		}

		return null;
	}

	/**
	 * Replaces a variable in config.ini
	 * @param props properties containing entries from the
	 * @param source the string to replace the var in
	 * @param var the variable to replace
	 * @param prop the property to lookup for a replacement value
	 * @param defaultValue value to use if the property can't be found
	 * @return source string with the variable replaced with the proper value
	 */
	private String substituteVar(Properties props, String source, String var, String prop, File defaultValue) {
		String value = props.getProperty(prop);
		if (value == null) {
			value = defaultValue.getAbsolutePath();
		}
		return value + source.substring(var.length());
	}

	private boolean isNullOrEqual(Object o1, Object o2) {
		if (o1 == null) {
			return o2 == null;
		}
		if (o2 == null) {
			return false;
		}
		return o1.equals(o2);
	}

	@Override
	public String toString() {
		return new StringBuilder("Installation ").append(fHome).append(' ') //$NON-NLS-1$
				.append(fConfiguration == null ? "Default Configuration" : fConfiguration).toString(); //$NON-NLS-1$
	}

	public void reload() {
		clearResolutionStatus();
	}

}
