/*=============================================================================#
 # Copyright (c) 2012, 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.internal.r.core;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IProject;
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.statet.internal.r.core.sourcemodel.RModelIndex;
import org.eclipse.statet.internal.r.core.sourcemodel.RModelManagerImpl;
import org.eclipse.statet.r.core.RProjects;


public class ResourceTracker implements IResourceChangeListener {
	
	
	private final RModelManagerImpl modelManager;
	
	private final Map<IProject, RProjectNature> knownProjects= new HashMap<>();
	
	
	public ResourceTracker(final RModelManagerImpl manager) {
		this.modelManager= manager;
		
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this,
				IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.PRE_DELETE );
	}
	
	
	public void dispose() {
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
	}
	
	
	public void register(final IProject project, final RProjectNature rProject) {
		synchronized (this.knownProjects) {
			this.knownProjects.put(project, rProject);
		}
	}
	
	public void unregister(final IProject project) {
		final RProjectNature rProject;
		synchronized (this.knownProjects) {
			rProject= this.knownProjects.remove(project);
		}
		if (rProject != null) {
			final RModelIndex index= this.modelManager.getIndex();
			if (index != null) {
				index.updateProjectConfigRemoved(project);
			}
		}
	}
	
	@Override
	public void resourceChanged(final IResourceChangeEvent event) {
		final IResource resource= event.getResource();
		if (resource instanceof IProject) {
			final IProject project= (IProject) resource;
			
			if (project.isOpen()) {
				try {
					if (project.hasNature(RProjects.R_NATURE_ID)) {
						final RModelIndex index= this.modelManager.getIndex();
						if (index != null) {
							switch (event.getType()) {
							case IResourceChangeEvent.PRE_CLOSE:
								index.updateProjectConfigClosed(project);
								break;
							case IResourceChangeEvent.PRE_DELETE:
								index.updateProjectConfigRemoved(project);
								break;
							default:
								break;
							}
						}
					}
				}
				catch (final CoreException e) {}
			}
			
			final RProjectNature rProject;
			synchronized (this.knownProjects) {
				rProject= this.knownProjects.remove(project);
			}
			if (rProject != null) {
				rProject.dispose();
			}
		}
	}
	
}
