package org.eclipse.e4.tools.emf.ui.internal.common.properties;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.List;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.ResourceBundle.Control;

import javax.inject.Inject;
import javax.inject.Named;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.translation.TranslationService;
import org.eclipse.e4.tools.services.impl.ResourceBundleHelper;
import org.eclipse.e4.tools.services.impl.ResourceBundleTranslationProvider;
import org.osgi.framework.Constants;

public class ProjectOSGiTranslationProvider extends ResourceBundleTranslationProvider {

	public static final String META_INF_DIRECTORY_NAME = "META-INF"; //$NON-NLS-1$
	public static final String MANIFEST_DEFAULT_PATH = "META-INF/MANIFEST.MF"; //$NON-NLS-1$

	/**
	 * The {@link IProject} this translation provider is connected to
	 */
	private IProject project;
	/**
	 * The manifest header identifying the base name of the bundle's
	 * localization entries.
	 */
	private String basename;
	/**
	 * The Locale to use for translations.
	 */
	private Locale locale;

	/**
	 * @param project
	 *            The {@link IProject} this translation provider should be
	 *            connected to.
	 * @param locale
	 *            The initial {@link Locale} for which this translation provider
	 *            should be created.
	 */
	// TODO change parameter to Locale instead of String once we break e4 tools
	// compatibility with Luna
	public ProjectOSGiTranslationProvider(IProject project, String locale) {
		// create the translation provider with no initial ResourceBundle as we
		// need to calculate it first
		super(null);

		this.project = project;
		this.project.getWorkspace().addResourceChangeListener(new IResourceChangeListener() {

			@Override
			public void resourceChanged(IResourceChangeEvent event) {
				if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
					try {
						event.getDelta().accept(new IResourceDeltaVisitor() {

							@Override
							public boolean visit(IResourceDelta delta) throws CoreException {
								return ProjectOSGiTranslationProvider.this.visit(delta);
							}
						});
					} catch (final CoreException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		});
		setLocale(locale, false);

		final IFile f = this.project.getFile(MANIFEST_DEFAULT_PATH);
		if (f.exists()) {
			handleManifestChange(f);
		} else {
			basename = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
		}
	}

	// TODO remove once we break e4 tools
	// compatibility with Luna
	@Inject
	void setLocale(@Named(TranslationService.LOCALE) String locale, @Optional Boolean performUpdate) {
		try {
			this.locale = locale == null ? Locale.getDefault() : ResourceBundleHelper.toLocale(locale);
		} catch (final Exception e) {
			this.locale = Locale.getDefault();
		}

		if (performUpdate == null || performUpdate) {
			updateResourceBundle();
		}
	}

	@Inject
	void setLocale(@Named(TranslationService.LOCALE) Locale locale, @Optional Boolean performUpdate) {
		this.locale = locale == null ? Locale.getDefault() : locale;

		if (performUpdate == null || performUpdate) {
			updateResourceBundle();
		}
	}

	/**
	 *
	 * @param delta
	 *            The resource delta that represents the changes in the state of
	 *            a resource tree between two discrete points in time.
	 * @return <code>true</code> if the resource delta's children should be
	 *         visited; <code>false</code> if they should be skipped.
	 */
	boolean visit(IResourceDelta delta) {
		if (delta.getResource() instanceof IWorkspaceRoot) {
			return true;
		} else if (delta.getResource().equals(project)) {
			return true;
		} else if (delta.getResource().getProjectRelativePath().toString().equals(META_INF_DIRECTORY_NAME)) {
			return true;
		} else if (delta.getResource().getProjectRelativePath().toString().equals(MANIFEST_DEFAULT_PATH)) {
			handleManifestChange((IFile) delta.getResource());
			return false;
		} else if (delta.getResource() instanceof IFile) {
			final String filename = ((IFile) delta.getResource()).getName();
			// extract base bundle name out of local basename
			final String fileBaseName = basename.substring(basename.lastIndexOf("/") + 1, basename.length()); //$NON-NLS-1$
			if (filename.startsWith(fileBaseName)) {
				updateResourceBundle();
				return false;
			}
		}

		if (delta.getResource().getProjectRelativePath().toString().equals(basename)) {
			updateResourceBundle();
			return false;
		}

		final String[] p = basename.split("/"); //$NON-NLS-1$
		int i = 0;
		String path = ""; //$NON-NLS-1$
		do {
			path += p[i];
			if (delta.getResource().getProjectRelativePath().toString().equals(path)) {
				return true;
			}
			path += "/"; //$NON-NLS-1$
		} while (++i < p.length);

		return false;
	}

	/**
	 * Will check if the manifest header identifying the base name of the
	 * bundle's localization entries has changed and if so it will update the
	 * underlying {@link ResourceBundle} and clear the caches.
	 *
	 * @param file
	 *            The reference to the manifest file of the current project.
	 */
	private void handleManifestChange(IFile file) {
		try {
			if (!file.isAccessible()) {
				return;
			}
			final String newValue = extractBasenameFromManifest(file);

			if (!newValue.equals(basename)) {
				basename = newValue;
				if (basename != null) {
					updateResourceBundle();
				}
			}

		} catch (final CoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (final IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * Extracts the manifest header identifying the base name of the bundle's
	 * localization entries.
	 *
	 * @param file
	 *            The reference to the manifest file of the current project.
	 * @return The manifest header identifying the base name of the bundle's
	 *         localization entries.
	 * @throws CoreException
	 *             If loading the contents of the given {@link IFile} fails
	 * @throws IOException
	 *             If reading out of the given file fails.
	 *
	 * @see IFile#getContents()
	 */
	public static String extractBasenameFromManifest(IFile file) throws CoreException, IOException {
		String newValue = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
		try (final InputStream in = file.getContents();
				final BufferedReader r = new BufferedReader(new InputStreamReader(in))) {
			String line;
			while ((line = r.readLine()) != null) {
				if (line.startsWith(Constants.BUNDLE_LOCALIZATION)) {
					newValue = line.substring(Constants.BUNDLE_LOCALIZATION.length() + 1).trim();
					break;
				}
			}

		}
		return newValue;
	}

	/**
	 * Reloads the underlying ResourceBundle.
	 */
	protected void updateResourceBundle() {
		setResourceBundle(ResourceBundleHelper.getEquinoxResourceBundle(basename, locale,
				new ProjectResourceBundleControl(true), new ProjectResourceBundleControl(false)));
	}

	/**
	 * Specialization of {@link Control} which loads the {@link ResourceBundle} by using file structures of a project
	 * instead of using a classloader.
	 *
	 * @author Dirk Fauth
	 */
	class ProjectResourceBundleControl extends ResourceBundle.Control {

		/**
		 * Flag to determine whether the default locale should be used as
		 * fallback locale in case there is no {@link ResourceBundle} found for
		 * the specified locale.
		 */
		private final boolean useFallback;

		/**
		 * @param useFallback
		 *            <code>true</code> if the default locale should be used as
		 *            fallback locale in the search path or <code>false</code> if there should be no fallback.
		 */
		ProjectResourceBundleControl(boolean useFallback) {
			this.useFallback = useFallback;
		}

		@SuppressWarnings("resource")
		@Override
		public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader,
				boolean reload) throws IllegalAccessException, InstantiationException, IOException {

			final String bundleName = toBundleName(baseName, locale);
			ResourceBundle bundle = null;
			if (format.equals("java.properties")) { //$NON-NLS-1$
				final String resourceName = toResourceName(bundleName, "properties"); //$NON-NLS-1$
				InputStream stream = null;
				try {
					stream = AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>() {
						@Override
						public InputStream run() throws IOException {
							return getResourceAsStream(resourceName);
						}
					});
				} catch (final PrivilegedActionException e) {
					throw (IOException) e.getException();
				}
				if (stream != null) {
					try {
						bundle = new PropertyResourceBundle(stream);
					} finally {
						stream.close();
					}
				}
			} else {
				throw new IllegalArgumentException("unknown format: " + format); //$NON-NLS-1$
			}
			return bundle;
		}

		/**
		 * Loads the properties file by using the {@link IProject} of the {@link ProjectOSGiTranslationProvider}.
		 *
		 * @param name
		 * @return The {@link InputStream} to the properties file to load
		 */
		protected InputStream getResourceAsStream(String name) {
			final IFile f = project.getFile(name);
			try {
				if (f.exists()) {
					return f.getContents();
				}
				return null;
			} catch (final CoreException e) {
				return null;
			}
		}

		@Override
		public List<String> getFormats(String baseName) {
			return FORMAT_PROPERTIES;
		}

		@Override
		public Locale getFallbackLocale(String baseName, Locale locale) {
			return useFallback ? super.getFallbackLocale(baseName, locale) : null;
		}

		// this implementation simply doesn't cache the values in the
		// ResourceBundle. If we recognize performance issues in the
		// Application Model Editor because of this we should consider
		// returning 0 here and overriding needsReload() with the information
		// which bundle needs to be reloaded
		@Override
		public long getTimeToLive(String baseName, Locale locale) {
			return TTL_DONT_CACHE;
		}
	}
}
