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

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.inject.Named;

import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.core.services.nls.Translation;
import org.eclipse.e4.tools.emf.ui.common.IModelResource;
import org.eclipse.e4.tools.emf.ui.internal.Messages;
import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
import org.eclipse.e4.tools.services.IResourcePool;
import org.eclipse.e4.ui.model.application.commands.impl.CommandsPackageImpl;
import org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl;
import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuPackageImpl;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

public class ExternalizeStringHandler {

	@Execute
	public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell, @Translation Messages messages, IModelResource resource, IResourcePool pool, IProject project) {
		TitleAreaDialog dialog = new ExtractionDialog(shell, messages, resource, resource.getRoot(), pool, project);
		dialog.open();
	}

	static class ExtractionDialog extends TitleAreaDialog {
		private Messages messages;
		private IObservableList list;
		private IResourcePool pool;
		private IProject project;
		private CheckboxTableViewer viewer;
		private IModelResource resource;

		public ExtractionDialog(Shell parentShell, Messages messages, IModelResource resource, IObservableList list, IResourcePool pool, IProject project) {
			super(parentShell);
			this.messages = messages;
			this.list = list;
			this.pool = pool;
			this.project = project;
			this.resource = resource;
		}

		@Override
		protected Control createDialogArea(Composite parent) {
			getShell().setText(messages.ExternalizeStringHandler_Dialog_ShellTitle);
			setTitle(messages.ExternalizeStringHandler_Dialog_DialogTitle);
			setMessage(messages.ExternalizeStringHandler_Dialog_DialogMessage);
			setTitleImage(pool.getImageUnchecked(ResourceProvider.IMG_Wizban16_extstr_wiz));

			Composite container = (Composite) super.createDialogArea(parent);
			Table t = new Table(container, SWT.BORDER | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CHECK);
			GridData gd = new GridData(GridData.FILL_BOTH);
			gd.heightHint = t.getItemHeight() * 15;
			t.setLayoutData(gd);
			t.setHeaderVisible(true);
			t.setLinesVisible(true);

			viewer = new CheckboxTableViewer(t);

			{
				TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
				column.setLabelProvider(new ColumnLabelProvider() {
					@Override
					public String getText(Object element) {
						return ""; //$NON-NLS-1$
					}
				});
			}

			{
				TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
				column.getColumn().setText(messages.ExternalizeStringHandler_Dialog_ElementName);
				column.setLabelProvider(new ColumnLabelProvider() {
					@Override
					public String getText(Object element) {
						Entry e = (Entry) element;
						// FIXME We need the label provider
						return e.object.eClass().getName();
					}
				});
			}

			{
				TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
				column.getColumn().setText(messages.ExternalizeStringHandler_Dialog_AttributeName);
				column.setLabelProvider(new ColumnLabelProvider() {
					@Override
					public String getText(Object element) {
						Entry e = (Entry) element;
						// FIXME We need the label provider
						return e.feature.getName();
					}
				});
			}

			{
				TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
				column.getColumn().setText(messages.ExternalizeStringHandler_Dialog_Key);
				column.setLabelProvider(new ColumnLabelProvider() {
					@Override
					public String getText(Object element) {
						Entry e = (Entry) element;
						return e.key;
					}
				});
			}

			{
				TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
				column.getColumn().setText(messages.ExternalizeStringHandler_Dialog_Value);
				column.setLabelProvider(new ColumnLabelProvider() {
					@Override
					public String getText(Object element) {
						Entry e = (Entry) element;
						return e.value;
					}
				});
			}

			List<Entry> entries = new ArrayList<>();
			TreeIterator<EObject> it = EcoreUtil.getAllContents(list);

			List<String> ids = new ArrayList<>();

			List<EStructuralFeature> translatedFeatures = new ArrayList<>();
			translatedFeatures.add(UiPackageImpl.Literals.UI_LABEL__LABEL);
			translatedFeatures.add(UiPackageImpl.Literals.UI_LABEL__TOOLTIP);
			translatedFeatures.add(CommandsPackageImpl.Literals.COMMAND__COMMAND_NAME);
			translatedFeatures.add(CommandsPackageImpl.Literals.COMMAND__DESCRIPTION);
			translatedFeatures.add(CommandsPackageImpl.Literals.CATEGORY__NAME);
			translatedFeatures.add(CommandsPackageImpl.Literals.CATEGORY__DESCRIPTION);
			translatedFeatures.add(org.eclipse.e4.ui.model.application.ui.basic.impl.BasicPackageImpl.Literals.PART__DESCRIPTION);
			translatedFeatures.add(BasicPackageImpl.Literals.PART_DESCRIPTOR__DESCRIPTION);
			translatedFeatures.add(MenuPackageImpl.Literals.MENU_ELEMENT__MNEMONICS);

			while (it.hasNext()) {
				EObject o = it.next();

				for (EAttribute a : o.eClass().getEAllAttributes()) {
					if (translatedFeatures.contains(a)) {
						String v = (String) o.eGet(a);

						if (v != null && v.startsWith("%")) { //$NON-NLS-1$
							ids.add(v);
						}
					}
				}
			}

			Properties properties = getBaseProperties();
			for (Object o : properties.keySet()) {
				ids.add(o.toString());
			}

			it = EcoreUtil.getAllContents(list);
			while (it.hasNext()) {
				EObject o = it.next();

				for (EAttribute a : o.eClass().getEAllAttributes()) {
					if (translatedFeatures.contains(a)) {
						String v = (String) o.eGet(a);
						if (v != null && v.trim().length() > 0 && !v.startsWith("%")) { //$NON-NLS-1$
							String id = findId(ids, o.eClass().getName().toLowerCase() + "." + a.getName().toLowerCase()); //$NON-NLS-1$
							entries.add(new Entry(o, a, id, v));
							ids.add(id);
						}
					}
				}
			}
			viewer.setContentProvider(new ArrayContentProvider());
			viewer.setInput(entries);
			viewer.setAllChecked(true);

			for (int i = 1; i < viewer.getTable().getColumnCount(); i++) {
				TableColumn c = viewer.getTable().getColumn(i);
				c.pack();
				if (c.getWidth() < 120) {
					c.setWidth(120);
				}
			}

			return container;
		}

		@Override
		protected void okPressed() {
			Object[] els = viewer.getCheckedElements();
			if (els.length > 0) {
				try {
					IFile f = getBasePropertyFile();

					StringBuilder b = new StringBuilder(System.getProperty("line.separator")); //$NON-NLS-1$
					for (Object o : els) {
						Entry e = (Entry) o;
						b.append(e.key + " = " + e.value + System.getProperty("line.separator")); //$NON-NLS-1$//$NON-NLS-2$
					}

					try (ByteArrayInputStream stream = new ByteArrayInputStream(b.toString().getBytes())) {
						if (f.exists()) {
							f.appendContents(stream, IResource.KEEP_HISTORY, new NullProgressMonitor());
						} else {
							createParent(f.getParent());
							f.create(stream, IResource.KEEP_HISTORY, new NullProgressMonitor());
						}
					}

					for (Object o : els) {
						Entry e = (Entry) o;
						Command cmd = SetCommand.create(resource.getEditingDomain(), e.object, e.feature, "%" + e.key); //$NON-NLS-1$

						if (cmd.canExecute()) {
							resource.getEditingDomain().getCommandStack().execute(cmd);
						}
					}
					super.okPressed();
				} catch (CoreException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}

		private void createParent(IContainer container) throws CoreException {
			if (!container.exists()) {

				createParent(container.getParent());

				if (container instanceof IFolder) {
					IFolder f = (IFolder) container;
					f.create(true, true, new NullProgressMonitor());
				}
			}
		}

		private IFile getBasePropertyFile() throws CoreException, IOException {
			IFile file = project.getFile("META-INF/MANIFEST.MF"); //$NON-NLS-1$
			String base = ProjectOSGiTranslationProvider.extractBasenameFromManifest(file);
			return project.getFile(base + ".properties"); //$NON-NLS-1$
		}

		private Properties getBaseProperties() {
			Properties prop = new Properties();
			try {
				IFile f = getBasePropertyFile();
				if (f.exists()) {

					try (InputStream in = f.getContents()) {
						prop.load(in);
					}
				}
			} catch (CoreException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			return prop;
		}
	}

	private static String findId(List<String> ids, String prefix) {
		int count = 1;
		String id = prefix + "." + count; //$NON-NLS-1$
		while (ids.contains(id)) {
			id = prefix + "." + ++count; //$NON-NLS-1$
		}
		return id;
	}

	static class Entry {
		private EObject object;
		private EStructuralFeature feature;
		private String key;
		private String value;

		public Entry(EObject object, EStructuralFeature feature, String key, String value) {
			this.object = object;
			this.feature = feature;
			this.key = key;
			this.value = value;
		}
	}
}