/*******************************************************************************
 *  Copyright (c) 2008, 2009 IBM Corporation 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
 * 
 *  Contributors:
 *     IBM Corporation - initial API and implementation
 *     Code 9 - ongoing development
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.extensionlocation;

import java.io.*;
import java.net.URI;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.provisional.p2.artifact.repository.*;
import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey;
import org.eclipse.equinox.internal.provisional.spi.p2.repository.AbstractRepository;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.BundleContext;

public class ExtensionLocationArtifactRepository extends AbstractRepository implements IFileArtifactRepository, Constants {

	public static final String TYPE = "org.eclipse.equinox.p2.extensionlocation.artifactRepository"; //$NON-NLS-1$
	public static final Integer VERSION = new Integer(1);
	public static final List STANDARD_P2_REPOSITORY_FILE_NAMES = Arrays.asList(new Object[] {"artifacts.xml", "content.xml", "compositeArtifacts.xml", "compositeContent.xml"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$

	IFileArtifactRepository artifactRepository;
	private File base;
	private Object state = SiteListener.UNINITIALIZED;

	/*
	 * Return the location of a local repository based on
	 * the given URL.
	 */
	public static URI getLocalRepositoryLocation(URI location) {
		BundleContext context = Activator.getContext();
		String stateDirName = Integer.toString(location.toString().hashCode());
		File bundleData = context.getDataFile(null);
		File stateDir = new File(bundleData, stateDirName);
		return stateDir.toURI();
	}

	/*
	 * Constructor for the class. Return a new extension location repository based on 
	 * the given url and nested repository.
	 */
	public ExtensionLocationArtifactRepository(URI location, IFileArtifactRepository repository, IProgressMonitor monitor) throws ProvisionException {
		super(Activator.getRepositoryName(location), TYPE, VERSION.toString(), location, null, null, null);
		this.artifactRepository = repository;
		this.base = getBaseDirectory(location);
	}

	public synchronized void ensureInitialized() {
		if (state == SiteListener.INITIALIZED || state == SiteListener.INITIALIZING)
			return;
		// if the repo has not been synchronized for us already, synchronize it.
		// Note: this will reload "artifactRepository"
		SiteListener.synchronizeRepositories(null, this, base);
	}

	void reload() {
		try {
			ExtensionLocationArtifactRepository repo = (ExtensionLocationArtifactRepository) new ExtensionLocationArtifactRepositoryFactory().load(getLocation(), 0, null);
			artifactRepository = repo.artifactRepository;
			base = repo.base;
		} catch (ProvisionException e) {
			//unexpected
			e.printStackTrace();
			throw new IllegalStateException(e.getMessage());
		}
	}

	void state(Object value) {
		state = value;
	}

	public static void validate(URI location, IProgressMonitor monitor) throws ProvisionException {
		File base = getBaseDirectory(location);
		if (new File(base, EXTENSION_LOCATION).exists() || location.getPath().endsWith(EXTENSION_LOCATION))
			return;
		if (containsUpdateSiteFile(base)) {
			String message = NLS.bind(Messages.error_update_site, location.toString());
			throw new ProvisionException(new Status(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_NOT_FOUND, message, null));
		}
		if (containsStandardP2Repository(base)) {
			String message = NLS.bind(Messages.error_p2_repository, location.toString());
			throw new ProvisionException(new Status(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_NOT_FOUND, message, null));
		}
	}

	private static boolean containsStandardP2Repository(File base) {
		File[] foundRepos = base.listFiles(new FilenameFilter() {
			public boolean accept(File dir, String name) {
				return (STANDARD_P2_REPOSITORY_FILE_NAMES.contains(name));
			}
		});
		return foundRepos.length > 0;
	}

	private static boolean containsUpdateSiteFile(File base) {
		String[] fileNames = base.list();
		if (fileNames == null)
			return false;
		for (int i = 0; i < fileNames.length; i++) {
			if (fileNames[i].endsWith(DOT_XML) && fileNames[i].indexOf(SITE) != -1)
				return true;
		}
		return false;
	}

	public static File getBaseDirectory(URI uri) throws ProvisionException {
		if (!FILE.equals(uri.getScheme()))
			throw new ProvisionException(new Status(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_NOT_FOUND, Messages.not_file_protocol, null));

		String path = URIUtil.toFile(uri).getAbsolutePath();
		if (path.endsWith(EXTENSION_LOCATION))
			path = path.substring(0, path.length() - EXTENSION_LOCATION.length());
		File base = new File(path);

		if (!base.isDirectory())
			throw new ProvisionException(new Status(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_NOT_FOUND, NLS.bind(Messages.not_directory, uri.toString()), null));

		if (isBaseDirectory(base))
			return base;

		File eclipseBase = new File(base, ECLIPSE);
		if (isBaseDirectory(eclipseBase))
			return eclipseBase;

		throw new ProvisionException(new Status(IStatus.ERROR, Activator.ID, ProvisionException.REPOSITORY_NOT_FOUND, NLS.bind(Messages.not_eclipse_extension, uri.toString()), null));
	}

	private static boolean isBaseDirectory(File base) {
		File plugins = new File(base, PLUGINS);
		File features = new File(base, FEATURES);

		return plugins.isDirectory() || features.isDirectory();
	}

	public void addDescriptor(IArtifactDescriptor descriptor) {
		throw new UnsupportedOperationException();
	}

	public void addDescriptors(IArtifactDescriptor[] descriptors) {
		throw new UnsupportedOperationException();
	}

	public void removeAll() {
		throw new UnsupportedOperationException();
	}

	public void removeDescriptor(IArtifactDescriptor descriptor) {
		throw new UnsupportedOperationException();
	}

	public void removeDescriptor(IArtifactKey key) {
		throw new UnsupportedOperationException();
	}

	public boolean contains(IArtifactDescriptor descriptor) {
		ensureInitialized();
		return artifactRepository.contains(descriptor);
	}

	public boolean contains(IArtifactKey key) {
		ensureInitialized();
		return artifactRepository.contains(key);
	}

	public IStatus getArtifact(IArtifactDescriptor descriptor, OutputStream destination, IProgressMonitor monitor) {
		ensureInitialized();
		return artifactRepository.getArtifact(descriptor, destination, monitor);
	}

	public IStatus getRawArtifact(IArtifactDescriptor descriptor, OutputStream destination, IProgressMonitor monitor) {
		ensureInitialized();
		return artifactRepository.getRawArtifact(descriptor, destination, monitor);
	}

	public IArtifactDescriptor[] getArtifactDescriptors(IArtifactKey key) {
		ensureInitialized();
		return artifactRepository.getArtifactDescriptors(key);
	}

	public IArtifactKey[] getArtifactKeys() {
		ensureInitialized();
		return artifactRepository.getArtifactKeys();
	}

	public IStatus getArtifacts(IArtifactRequest[] requests, IProgressMonitor monitor) {
		ensureInitialized();
		return artifactRepository.getArtifacts(requests, monitor);
	}

	public OutputStream getOutputStream(IArtifactDescriptor descriptor) throws ProvisionException {
		ensureInitialized();
		return artifactRepository.getOutputStream(descriptor);
	}

	public File getArtifactFile(IArtifactKey key) {
		ensureInitialized();
		return artifactRepository.getArtifactFile(key);
	}

	public File getArtifactFile(IArtifactDescriptor descriptor) {
		ensureInitialized();
		return artifactRepository.getArtifactFile(descriptor);
	}

	public Map getProperties() {
		ensureInitialized();
		return artifactRepository.getProperties();
	}

	public String setProperty(String key, String value) {
		ensureInitialized();
		String oldValue = artifactRepository.setProperty(key, value);
		// if the value didn't really change then just return
		if (oldValue == value || (oldValue != null && oldValue.equals(value)))
			return oldValue;
		// we want to re-initialize if we are changing the site policy or plug-in list
		if (!SiteListener.SITE_LIST.equals(key) && !SiteListener.SITE_POLICY.equals(key))
			return oldValue;
		state = SiteListener.UNINITIALIZED;
		ensureInitialized();
		return oldValue;
	}
}
