/*******************************************************************************
 * Copyright (c) 2016 QNX Software Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.eclipse.cdt.internal.core.build;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CProjectNature;
import org.eclipse.cdt.core.build.ICBuildConfiguration;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager2;
import org.eclipse.cdt.core.build.ICBuildConfigurationProvider;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.build.IToolChainManager;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.internal.core.model.CModelManager;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

public class CBuildConfigurationManager implements ICBuildConfigurationManager, ICBuildConfigurationManager2, IResourceChangeListener {

	private static class Provider {
		private String id;
		private String natureId;
		private IConfigurationElement element;
		private ICBuildConfigurationProvider provider;

		public Provider(IConfigurationElement element) {
			this.id = element.getAttribute("id"); //$NON-NLS-1$
			this.natureId = element.getAttribute("natureId"); //$NON-NLS-1$
			this.element = element;
		}

		public String getId() {
			return id;
		}

		public ICBuildConfigurationProvider getProvider() {
			if (provider == null) {
				try {
					provider = (ICBuildConfigurationProvider) element.createExecutableExtension("class"); //$NON-NLS-1$
				} catch (CoreException e) {
					CCorePlugin.log(e.getStatus());
				}
			}
			return provider;
		}

		public boolean supports(IProject project) {
			try {
				if (natureId != null) {
					return project.hasNature(natureId);
				}
			} catch (CoreException e) {
				CCorePlugin.log(e.getStatus());
			}
			return false;
		}
	}

	private Map<String, Provider> providers;
	private Map<IBuildConfiguration, ICBuildConfiguration> configs = new HashMap<>();
	private Set<IBuildConfiguration> noConfigs = new HashSet<>();

	public CBuildConfigurationManager() {
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
	}

	public void dispose() {
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
	}

	private synchronized void initProviders() {
		if (providers == null) {
			providers = new HashMap<>();

			IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID,
					"buildConfigProvider"); //$NON-NLS-1$
			for (IConfigurationElement element : point.getConfigurationElements()) {
				Provider provider = new Provider(element);
				providers.put(provider.getId(), provider);
			}
		}
	}

	private Provider getProviderDelegate(String id) {
		return providers.get(id);
	}

	@Override
	public ICBuildConfigurationProvider getProvider(String id) {
		initProviders();
		Provider provider = providers.get(id);
		return provider != null ? provider.getProvider() : null;
	}
	
	public ICBuildConfigurationProvider getProvider(String id, IProject project) {
		initProviders();
		Provider provider = getProviderDelegate(id);
		if (provider != null && provider.supports(project)) {
			return provider.getProvider();
		}
		return null;
	}

	public ICBuildConfigurationProvider getProvider(IProject project) throws CoreException {
		initProviders();
		for (Provider provider : providers.values()) {
			if (provider.supports(project)) {
				return provider.getProvider();
			}
		}
		return null;
	}

	@Override
	public boolean hasConfiguration(ICBuildConfigurationProvider provider, IProject project,
			String configName) throws CoreException {
		String name = provider.getId() + '/' + configName;
		return project.hasBuildConfig(name);
	}

	@Override
	public IBuildConfiguration createBuildConfiguration(ICBuildConfigurationProvider provider,
			IProject project, String configName, IProgressMonitor monitor) throws CoreException {
		String name = provider.getId() + '/' + configName;

		Set<String> names = new HashSet<>();
		for (IBuildConfiguration config : project.getBuildConfigs()) {
			names.add(config.getName());
		}

		IProjectDescription desc = project.getDescription();
		names.add(name);
		desc.setBuildConfigs(names.toArray(new String[names.size()]));
		project.setDescription(desc, monitor);

		return project.getBuildConfig(name);
	}

	@Override
	public void addBuildConfiguration(IBuildConfiguration buildConfig, ICBuildConfiguration cConfig) {
		synchronized (configs) {
			configs.put(buildConfig, cConfig);
		}

		// reset the binary parsers
		CModelManager.getDefault().resetBinaryParser(buildConfig.getProject());
	}

	@Override
	public void recheckConfigs() {
		initProviders();
		ICBuildConfiguration config = null;
		Set<IProject> projects = new HashSet<>();
		synchronized (configs) {
			Iterator<IBuildConfiguration> iterator = noConfigs.iterator();
			while (iterator.hasNext()) {
				IBuildConfiguration buildConfig = iterator.next();
				String configName = null;
				ICBuildConfigurationProvider provider = null;
				if (IBuildConfiguration.DEFAULT_CONFIG_NAME.equals(buildConfig.getName())) {
					configName = ICBuildConfiguration.DEFAULT_NAME;
					try {
						provider = getProvider(buildConfig.getProject());
					} catch (CoreException e) {
						continue;
					}
				} else {
					String[] segments = buildConfig.getName().split("/"); //$NON-NLS-1$
					if (segments.length == 2) {
						String providerId = segments[0];
						configName = segments[1];
						Provider delegate = getProviderDelegate(providerId);
						if (delegate != null && delegate.supports(buildConfig.getProject())) {
							provider = delegate.getProvider();
						}
					}
				}

				if (provider != null) {
					try {
						config = provider.getCBuildConfiguration(buildConfig, configName);
					} catch (CoreException e) {
						// do nothing
					}
					if (config != null) {
						iterator.remove();
						projects.add(buildConfig.getProject());
						configs.put(buildConfig, config);
					}
				}

			}
		}
		
		for (IProject project : projects) {
			// Do this outside of the synchronized block to avoid deadlock with
			// BinaryRunner
			CModelManager.getDefault().resetBinaryParser(project);
		}
	}
	
	@Override
	public ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig) throws CoreException {
		initProviders();
		ICBuildConfiguration config = null;
		boolean resetBinaryParser = false;
		synchronized (configs) {
			if (!noConfigs.contains(buildConfig)) {
				config = configs.get(buildConfig);
				if (config == null) {
					String configName = null;
					ICBuildConfigurationProvider provider = null;
					if (IBuildConfiguration.DEFAULT_CONFIG_NAME.equals(buildConfig.getName())) {
						configName = ICBuildConfiguration.DEFAULT_NAME;
						provider = getProvider(buildConfig.getProject());
					} else {
						String[] segments = buildConfig.getName().split("/"); //$NON-NLS-1$
						if (segments.length == 2) {
							String providerId = segments[0];
							configName = segments[1];
							Provider delegate = getProviderDelegate(providerId);
							if (delegate != null && delegate.supports(buildConfig.getProject())) {
								provider = delegate.getProvider();
							}
						}
					}

					if (provider != null) {
						try {
							config = provider.getCBuildConfiguration(buildConfig, configName);
						} catch (CoreException e) {
							IStatus status = e.getStatus();
							if (!status.getPlugin().equals(CCorePlugin.PLUGIN_ID)
									|| status.getCode() != CCorePlugin.STATUS_BUILD_CONFIG_NOT_VALID) {
								throw e;
							}
						}
						if (config != null) {
							configs.put(buildConfig, config);
							// Also make sure we reset the binary parser cache
							// for the new config
							resetBinaryParser = true;
						}
					}

					if (config == null) {
						noConfigs.add(buildConfig);
					}
				}
			}
		}

		if (resetBinaryParser) {
			// Do this outside of the synchronized block to avoid deadlock with
			// BinaryRunner
			CModelManager.getDefault().resetBinaryParser(buildConfig.getProject());
		}

		return config;
	}

	@Override
	public ICBuildConfiguration getBuildConfiguration(IProject project, IToolChain toolChain,
			String launchMode, IProgressMonitor monitor) throws CoreException {
		// First see if we have one
		for (IBuildConfiguration config : project.getBuildConfigs()) {
			ICBuildConfiguration cconfig = getBuildConfiguration(config);
			if (cconfig != null && cconfig.getToolChain().equals(toolChain)
					&& launchMode.equals(cconfig.getLaunchMode())) {
				return cconfig;
			}
		}

		// Nope, ask the provider to create one
		ICBuildConfigurationProvider provider = getProvider(project);
		if (provider != null) {
			// The provider will call us back to add in the new one
			return provider.createBuildConfiguration(project, toolChain, launchMode, monitor);
		} else {
			return null;
		}
	}

	@Override
	public ICBuildConfiguration getBuildConfiguration(IProject project, Map<String, String> properties,
			String launchMode, IProgressMonitor monitor) throws CoreException {
		IToolChainManager tcManager = CCorePlugin.getService(IToolChainManager.class);
		Collection<IToolChain> toolchains = tcManager.getToolChainsMatching(properties);
		if (toolchains.isEmpty()) {
			return null;
		}

		IToolChain toolChain = toolchains.iterator().next();
		return getBuildConfiguration(project, toolChain, launchMode, monitor);
	}

	@Override
	public void resourceChanged(IResourceChangeEvent event) {
		if (event.getType() == IResourceChangeEvent.PRE_CLOSE
				|| event.getType() == IResourceChangeEvent.PRE_DELETE) {
			if (event.getResource().getType() == IResource.PROJECT) {
				IProject project = event.getResource().getProject();
				try {
					if (!project.isOpen() || !project.hasNature(CProjectNature.C_NATURE_ID))
						return;
				} catch (CoreException e) {
					CCorePlugin.log(e.getStatus());
					return;
				}

				// Clean up the configMap
				try {
					for (IBuildConfiguration buildConfig : project.getBuildConfigs()) {
						configs.remove(buildConfig);
					}
				} catch (CoreException e) {
					CCorePlugin.log(e);
				}

				// Clean up the config settings
				Preferences parentNode = InstanceScope.INSTANCE.getNode(CCorePlugin.PLUGIN_ID).node("config"); //$NON-NLS-1$
				if (parentNode != null) {
					Preferences projectNode = parentNode.node(project.getName());
					if (projectNode != null) {
						try {
							projectNode.removeNode();
							parentNode.flush();
						} catch (BackingStoreException e) {
							CCorePlugin.log(e);
						}
					}
				}

				// Clean up the scanner info data
				IPath scannerInfoPath = CCorePlugin.getDefault().getStateLocation().append("infoCache") //$NON-NLS-1$
						.append(project.getName());
				Path directory = scannerInfoPath.toFile().toPath();
				if (!Files.exists(directory)) {
					return;
				}

				try {
					Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
						@Override
						public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
								throws IOException {
							Files.delete(file);
							return FileVisitResult.CONTINUE;
						}

						@Override
						public FileVisitResult postVisitDirectory(Path dir, IOException exc)
								throws IOException {
							Files.delete(dir);
							return FileVisitResult.CONTINUE;
						}
					});
				} catch (IOException e) {
					CCorePlugin.log(e);
				}
			}
		}
	}

	@Override
	public boolean supports(IProject project) throws CoreException {
		// Is this a CDT project?
		if (!CoreModel.hasCNature(project)) {
			return false;
		}

		initProviders();

		// First see if we have a build config registered
		for (IBuildConfiguration config : project.getBuildConfigs()) {
			if (configs.containsKey(config)) {
				return true;
			}
		}

		// See if one of the providers supports this project
		for (Provider provider : providers.values()) {
			if (provider.supports(project)) {
				return true;
			}
		}

		return false;
	}

}
