/*******************************************************************************
 *  Copyright (c) 2007, 2018 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 implementation and ideas 
 *   Code 9 - ongoing development
 *******************************************************************************/
package org.eclipse.equinox.internal.provisional.p2.directorywatcher;

import java.io.File;
import java.net.URI;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactDescriptor;
import org.eclipse.equinox.internal.p2.core.helpers.*;
import org.eclipse.equinox.internal.p2.update.Site;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.publisher.*;
import org.eclipse.equinox.p2.publisher.eclipse.BundlesAction;
import org.eclipse.equinox.p2.publisher.eclipse.FeaturesAction;
import org.eclipse.equinox.p2.query.*;
import org.eclipse.equinox.p2.repository.artifact.*;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;

public class RepositoryListener extends DirectoryChangeListener {
	public static final String ARTIFACT_FOLDER = "artifact.folder"; //$NON-NLS-1$
	public static final String ARTIFACT_REFERENCE = "artifact.reference"; //$NON-NLS-1$
	public static final String FILE_LAST_MODIFIED = "file.lastModified"; //$NON-NLS-1$
	public static final String FILE_NAME = "file.name"; //$NON-NLS-1$
	private final IMetadataRepository metadataRepository;
	private final CachingArtifactRepository artifactRepository;
	// at any point in time currentFiles is the list of files/dirs that the watcher has seen and 
	// believes to be on disk.
	private final Map<File, Long> currentFiles = new HashMap<>();
	private final Collection<File> polledSeenFiles = new HashSet<>();

	private EntryAdvice advice = new EntryAdvice();
	private PublisherInfo info;
	private IPublisherResult iusToAdd;
	private IPublisherResult iusToChange;

	/**
	 * Create a repository listener that watches the specified folder and generates repositories
	 * for its content.
	 * @param repositoryName the repository name to use for the repository
	 * @param properties the map of repository properties or <code>null</code>
	 */
	public RepositoryListener(String repositoryName, Map<String, String> properties) {
		URI location = getDefaultRepositoryLocation(this, repositoryName);
		metadataRepository = initializeMetadataRepository(repositoryName, location, properties);
		artifactRepository = initializeArtifactRepository(repositoryName, location, properties);
		initializePublisher();
	}

	public RepositoryListener(IMetadataRepository metadataRepository, IArtifactRepository artifactRepository) {
		this.artifactRepository = new CachingArtifactRepository(artifactRepository);
		this.metadataRepository = metadataRepository;
		initializePublisher();
	}

	private void initializePublisher() {
		info = new PublisherInfo();
		info.setArtifactRepository(artifactRepository);
		info.setMetadataRepository(metadataRepository);
		info.addAdvice(advice);
		info.setArtifactOptions(IPublisherInfo.A_INDEX | IPublisherInfo.A_NO_MD5);
	}

	protected CachingArtifactRepository initializeArtifactRepository(String name, URI repositoryLocation, Map<String, String> properties) {
		IArtifactRepositoryManager manager = getArtifactRepositoryManager();
		if (manager == null)
			throw new IllegalStateException(Messages.artifact_repo_manager_not_registered);

		try {
			IArtifactRepository result = manager.loadRepository(repositoryLocation, null);
			return result == null ? null : new CachingArtifactRepository(result);
		} catch (ProvisionException e) {
			//fall through and create a new repository
		}
		try {
			IArtifactRepository result = manager.createRepository(repositoryLocation, name, IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, properties);
			return result == null ? null : new CachingArtifactRepository(result);
		} catch (ProvisionException e) {
			LogHelper.log(e);
			throw new IllegalStateException(NLS.bind(Messages.failed_create_artifact_repo, repositoryLocation));
		}
	}

	protected IMetadataRepository initializeMetadataRepository(String name, URI repositoryLocation, Map<String, String> properties) {
		IMetadataRepositoryManager manager = getMetadataRepositoryManager();
		if (manager == null)
			throw new IllegalStateException(Messages.metadata_repo_manager_not_registered);

		try {
			return manager.loadRepository(repositoryLocation, null);
		} catch (ProvisionException e) {
			//fall through and create new repository
		}
		try {
			return manager.createRepository(repositoryLocation, name, IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, properties);
		} catch (ProvisionException e) {
			LogHelper.log(e);
			throw new IllegalStateException(NLS.bind(Messages.failed_create_metadata_repo, repositoryLocation));
		}
	}

	@Override
	public boolean added(File file) {
		return process(file, true);
	}

	@Override
	public boolean changed(File file) {
		return process(file, false);
	}

	@Override
	public boolean removed(File file) {
		// the IUs and artifacts associated with this file will get removed in stopPoll
		return currentFiles.containsKey(file);
	}

	private boolean process(File file, boolean isAddition) {
		boolean isDirectory = file.isDirectory();
		// is it a feature ?
		if (isDirectory && file.getParentFile() != null && file.getParentFile().getName().equals("features") && new File(file, "feature.xml").exists()) //$NON-NLS-1$ //$NON-NLS-2$)
			return processFeature(file, isAddition);
		// could it be a bundle ?
		if (isDirectory || file.getName().endsWith(".jar")) //$NON-NLS-1$
			return processBundle(file, isDirectory, isAddition);
		return false;
	}

	private boolean processBundle(File file, boolean isDirectory, boolean isAddition) {
		BundleDescription bundleDescription = BundlesAction.createBundleDescriptionIgnoringExceptions(file);
		if (bundleDescription == null)
			return false;

		advice.setProperties(file, file.lastModified(), file.toURI());
		return publish(new BundlesAction(new BundleDescription[] {bundleDescription}), isAddition);
		// TODO see bug 222370
		// we only want to return the bundle IU so must exclude all fragment IUs
		// not sure if this is still relevant but we should investigate.
	}

	private boolean processFeature(File file, boolean isAddition) {
		String link = metadataRepository.getProperties().get(Site.PROP_LINK_FILE);
		advice.setProperties(file, file.lastModified(), file.toURI(), link);
		return publish(new FeaturesAction(new File[] {file}), isAddition);
	}

	private boolean publish(IPublisherAction action, boolean isAddition) {
		IPublisherResult result = isAddition ? iusToAdd : iusToChange;
		return action.perform(info, result, new NullProgressMonitor()).isOK();
	}

	@Override
	public boolean isInterested(File file) {
		return true;
	}

	@Override
	public Long getSeenFile(File file) {
		Long lastSeen = currentFiles.get(file);
		if (lastSeen != null)
			polledSeenFiles.add(file);
		return lastSeen;
	}

	@Override
	public void startPoll() {
		iusToAdd = new PublisherResult();
		iusToChange = new PublisherResult();
		synchronizeCurrentFiles();
	}

	@Override
	public void stopPoll() {
		final Set<File> filesToRemove = new HashSet<>(currentFiles.keySet());
		filesToRemove.removeAll(polledSeenFiles);
		polledSeenFiles.clear();

		synchronizeMetadataRepository(filesToRemove);
		synchronizeArtifactRepository(filesToRemove);
		iusToAdd = null;
		iusToChange = null;
	}

	/**
	 * Flush all the pending changes to the metadata repository.
	 */
	private void synchronizeMetadataRepository(final Collection<File> removedFiles) {
		if (metadataRepository == null)
			return;
		final Collection<IInstallableUnit> changes = iusToChange.getIUs(null, null);
		// first remove any IUs that have changed or that are associated with removed files
		if (!removedFiles.isEmpty() || !changes.isEmpty()) {
			metadataRepository.removeInstallableUnits(changes);

			// create a query that will identify all ius related to removed files.
			// We convert the java.io.File objects to Strings before doing the comparison
			// because when we have large numbers of files, the performance is much better.
			// See bug 324353.
			Collection<String> paths = new HashSet<>(removedFiles.size());
			for (File file : removedFiles)
				paths.add(file.getAbsolutePath());
			IQuery<IInstallableUnit> removeQuery = QueryUtil.createMatchQuery( //
					"$1.exists(x | properties[$0] == x)", FILE_NAME, paths); //$NON-NLS-1$
			IQueryResult<IInstallableUnit> toRemove = metadataRepository.query(removeQuery, null);
			metadataRepository.removeInstallableUnits(toRemove.toUnmodifiableSet());
		}
		// Then add all the new IUs as well as the new copies of the ones that have changed
		Collection<IInstallableUnit> additions = iusToAdd.getIUs(null, null);
		additions.addAll(changes);
		if (!additions.isEmpty())
			metadataRepository.addInstallableUnits(additions);
	}

	/**
	 * Here the artifacts have all been added to the artifact repo.  Remove the
	 * descriptors related to any file that has been removed and flush the repo
	 * to ensure that all the additions and removals have been completed.
	 */
	private void synchronizeArtifactRepository(final Collection<File> removedFiles) {
		if (artifactRepository == null)
			return;
		if (!removedFiles.isEmpty()) {
			IArtifactDescriptor[] descriptors = artifactRepository.descriptorQueryable().query(ArtifactDescriptorQuery.ALL_DESCRIPTORS, null).toArray(IArtifactDescriptor.class);
			for (IArtifactDescriptor d : descriptors) {
				SimpleArtifactDescriptor descriptor = (SimpleArtifactDescriptor) d;
				String filename = descriptor.getRepositoryProperty(FILE_NAME);
				if (filename == null) {
					if (Tracing.DEBUG) {
						String message = NLS.bind(Messages.filename_missing, "artifact", descriptor.getArtifactKey()); //$NON-NLS-1$
						LogHelper.log(new Status(IStatus.ERROR, Constants.BUNDLE_ID, message, null));
					}
				} else {
					File artifactFile = new File(filename);
					if (removedFiles.contains(artifactFile))
						artifactRepository.removeDescriptor(descriptor);
				}
			}
		}
		artifactRepository.save();
	}

	/**
	 * Prime the list of current files that the listener knows about.  This traverses the 
	 * repos and looks for the related filename and modified timestamp information.
	 */
	private void synchronizeCurrentFiles() {
		currentFiles.clear();
		if (metadataRepository != null) {
			IQueryResult<IInstallableUnit> ius = metadataRepository.query(QueryUtil.createIUAnyQuery(), null);
			for (IInstallableUnit iu : ius) {
				String filename = iu.getProperty(FILE_NAME);
				if (filename == null) {
					if (Tracing.DEBUG) {
						String message = NLS.bind(Messages.filename_missing, "installable unit", iu.getId()); //$NON-NLS-1$
						LogHelper.log(new Status(IStatus.ERROR, Constants.BUNDLE_ID, message, null));
					}
				} else {
					File iuFile = new File(filename);
					Long iuLastModified = Long.valueOf(iu.getProperty(FILE_LAST_MODIFIED));
					currentFiles.put(iuFile, iuLastModified);
				}
			}
		}
		//
		//		// TODO  should we be doing this for the artifact repo?  the metadata repo should
		//		// be the main driver here.
		//		if (artifactRepository != null) {
		//			final List keys = new ArrayList(Arrays.asList(artifactRepository.getArtifactKeys()));
		//			for (Iterator it = keys.iterator(); it.hasNext();) {
		//				IArtifactKey key = (IArtifactKey) it.next();
		//				IArtifactDescriptor[] descriptors = artifactRepository.getArtifactDescriptors(key);
		//				for (int i = 0; i < descriptors.length; i++) {
		//					ArtifactDescriptor descriptor = (ArtifactDescriptor) descriptors[i];
		//					File artifactFile = new File(descriptor.getRepositoryProperty(FILE_NAME));
		//					Long artifactLastModified = new Long(descriptor.getRepositoryProperty(FILE_LAST_MODIFIED));
		//					currentFiles.put(artifactFile, artifactLastModified);
		//				}
		//			}
		//		}
	}

	public IMetadataRepository getMetadataRepository() {
		return metadataRepository;
	}

	public IArtifactRepository getArtifactRepository() {
		return artifactRepository;
	}

	private static IMetadataRepositoryManager getMetadataRepositoryManager() {
		BundleContext bundleContext = FrameworkUtil.getBundle(RepositoryListener.class).getBundleContext();
		return ServiceHelper.getService(bundleContext, IProvisioningAgent.class).getService(IMetadataRepositoryManager.class);
	}

	private static IArtifactRepositoryManager getArtifactRepositoryManager() {
		BundleContext bundleContext = FrameworkUtil.getBundle(RepositoryListener.class).getBundleContext();
		return ServiceHelper.getService(bundleContext, IProvisioningAgent.class).getService(IArtifactRepositoryManager.class);
	}

	private static URI getDefaultRepositoryLocation(Object object, String repositoryName) {
		Bundle bundle = FrameworkUtil.getBundle(object.getClass());
		BundleContext context = bundle.getBundleContext();
		File base = context.getDataFile(""); //$NON-NLS-1$
		File result = new File(base, "listener_" + repositoryName.hashCode()); //$NON-NLS-1$
		result.mkdirs();
		return result.toURI();
	}

}
