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.IResourceDelta;
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(event -> {
			if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
				try {
					event.getDelta().accept(delta -> 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((PrivilegedExceptionAction<InputStream>) () -> 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;
		}
	}
}
