/*******************************************************************************
 * Copyright (c) 2014, 2017 MEDEVIT, FHV 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:
 *     Marco Descher <marco@descher.at> - initial API and implementation
 *******************************************************************************/
package org.eclipse.e4.tools.emf.ui.internal.common.properties;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

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.MApplicationElement;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jface.dialogs.IDialogConstants;
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.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;

/**
 * This handler exports all Id values within the application model to a file for
 * static reference. Currently the location of this file is fixed to be in the
 * location of the selected projects main package with name
 * <code>AppModelId.java</code>.
 */
public class ExportIdsHandler {
	public static final String DEFAULT_APPMODELID_CLASSNAME = "AppModelId";

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

	static class ExportIdDialog extends TitleAreaDialog {
		private Messages messages;
		private IObservableList list;
		private IResourcePool pool;
		private JavaClass clazz;
		private CheckboxTableViewer viewer;
		private Text textClassName;

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

			clazz = new JavaClass();

			if (JavaProject.hasJavaNature(project)) {
				try {
					IJavaProject javaProject = JavaCore.create(project);
					for (IPackageFragmentRoot iPackageFragmentRoot : javaProject.getAllPackageFragmentRoots()) {
						if (iPackageFragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE) {
							clazz.packageFragment = iPackageFragmentRoot.createPackageFragment(project.getName(), false, new NullProgressMonitor());
							break;
						}
					}
				} catch (JavaModelException e) {
					e.printStackTrace();
				}
			} else {
				setErrorMessage(messages.ExportIdsHandler_Dialog_SelectProject);
				getButton(IDialogConstants.OK_ID).setEnabled(false);
			}
		}

		@Override
		protected Control createDialogArea(Composite parent) {
			getShell().setText(messages.ExportIdsHandler_Dialog_ShellTitle);
			setTitle(messages.ExportIdsHandler_Dialog_DialogTitle);
			setMessage(messages.ExportIdsHandler_Dialog_DialogMessage);
			setTitleImage(pool.getImageUnchecked(ResourceProvider.IMG_Wizban16_extstr_wiz));

			Composite content = (Composite) super.createDialogArea(parent);
			content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

			Composite container = new Composite(content, SWT.NONE);
			container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

			GridLayout gl = new GridLayout(2, false);
			gl.numColumns = 2;
			gl.marginBottom = 4;

			container.setLayout(gl);
			Label lblTargetClass = new Label(container, SWT.NONE);
			lblTargetClass.setText(messages.ExportIdsHandler_Dialog_TargetClassName);

			textClassName = new Text(container, SWT.BORDER);
			textClassName.setText(DEFAULT_APPMODELID_CLASSNAME);

			GridData gdcn = new GridData();
			gdcn.horizontalAlignment = SWT.FILL;
			gdcn.grabExcessHorizontalSpace = true;

			textClassName.setLayoutData(gdcn);
			Table t = new Table(container, SWT.BORDER | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CHECK);

			GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
			gd.heightHint = t.getItemHeight() * 18;
			container.setLayoutData(gd);

			GridData gd2 = new GridData(SWT.FILL, SWT.FILL, true, true);
			gd2.horizontalSpan = 2;
			gd2.heightHint = t.getItemHeight() * 17;
			t.setHeaderVisible(true);
			t.setLinesVisible(true);
			t.setLayoutData(gd2);

			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.ExportIdsHandler_Dialog_ElementName);
				column.setLabelProvider(new ColumnLabelProvider() {
					@Override
					public String getText(Object element) {
						Entry e = (Entry) element;
						return ((EObject) e.object).eClass().getName();
					}
				});
			}

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

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

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

			{
				Label l = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
				l.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false, 3, 1));
			}

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

			while (it.hasNext()) {
				Object next = it.next();
				if (next instanceof MApplicationElement) {
					MApplicationElement o = (MApplicationElement) next;
					if (o.getElementId() != null && o.getElementId().length() > 1) {
						String idFieldKey = findIdFieldKey(o);
						entries.add(new Entry(o, idFieldKey, o.getElementId()));
					}
				}
			}

			Collections.sort(entries);

			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() { // See AbstractNewClassWizard
			clazz.name = textClassName.getText();

			Object[] els = viewer.getCheckedElements();
			if (els.length > 0) {
				try {
					String content = compileFileContent(els);

					IPackageFragment fragment = clazz.packageFragment;
					String cuName = clazz.name + ".java"; //$NON-NLS-1$
					ICompilationUnit unit = fragment.getCompilationUnit(cuName);
					IResource resource = unit.getResource();
					IFile file = (IFile) resource;

					try (ByteArrayInputStream stream = new ByteArrayInputStream(content.toString().getBytes())) {
						if (file.exists()) {
							file.delete(true, new NullProgressMonitor());
						}

						createParent(file.getParent());
						// NPE
						file.create(stream, IResource.KEEP_HISTORY, new NullProgressMonitor());

					}
					super.okPressed();
				} catch (CoreException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		private String compileFileContent(Object[] els) {
			StringBuilder b = new StringBuilder();
			b.append("package " + clazz.packageFragment.getElementName() + ";" + System.getProperty("line.separator")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			b.append(System.getProperty("line.separator")); //$NON-NLS-1$
			b.append("public class " + clazz.name + " {" + System.getProperty("line.separator")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

			for (Object o : els) {
				Entry e = (Entry) o;
				b.append("\tpublic static final String " + e.idFieldKey + " = \"" + e.elementId + "\";" + System.getProperty("line.separator")); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
			}

			b.append("}"); //$NON-NLS-1$
			return b.toString();
		}

		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 static String findIdFieldKey(MApplicationElement object) {
		StringBuilder sb = new StringBuilder();
		sb.append(((EObject) object).eClass().getName());
		sb.append("_"); //$NON-NLS-1$
		sb.append(replaceInvalidChar(object.getElementId()));
		return sb.toString().toUpperCase();
	}

	private static String replaceInvalidChar(String elementId) {
		return elementId.replaceAll("[^A-Za-z0-9]", "_"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	private static class Entry implements Comparable<Entry> {
		private MApplicationElement object;
		private String idFieldKey;
		private String elementId;

		public Entry(MApplicationElement object, String idFieldKey, String elementId) {
			this.object = object;
			this.idFieldKey = idFieldKey;
			this.elementId = elementId;
		}

		@Override
		public int compareTo(Entry o) {
			return this.idFieldKey.compareTo(o.idFieldKey);
		}
	}

	/**
	 * @see org.eclipse.e4.internal.tools.wizards.classes.AbstractNewClassPage
	 */
	private static class JavaClass {
		private IPackageFragment packageFragment;
		private String name;
	}

}