/*******************************************************************************
 * Copyright (c) 2017 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
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.wizards;

import java.util.Arrays;
import java.util.HashSet;

import org.eclipse.swt.widgets.Display;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;

import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;

import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;

import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
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.corext.util.InfoFilesUtil;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.wizards.NewModuleInfoWizardPage;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaPluginImages;

public class NewModuleInfoWizard extends Wizard implements INewWizard {

	private static final String TRUE= "true"; //$NON-NLS-1$

	private NewModuleInfoWizardPage fPage;

	private static final String MODULE_INFO_JAVA_FILENAME= JavaModelUtil.MODULE_INFO_JAVA;

	private IPackageFragmentRoot fTargetPkgFragmentRoot;

	private IPackageFragmentRoot[] fPackageFragmentRoots;

	private IJavaProject fProject;

	public NewModuleInfoWizard(IJavaProject project, IPackageFragmentRoot[] packageFragmentRoots, IPackageFragmentRoot targetPkgFragmentRoot) {
		setDefaultPageImageDescriptor(JavaPluginImages.DESC_WIZBAN_NEWMODULE);
		setDialogSettings(JavaPlugin.getDefault().getDialogSettings());
		setWindowTitle(NewWizardMessages.NewModuleInfoWizard_title);
		fProject= project;
		fPackageFragmentRoots= packageFragmentRoots;
		if (targetPkgFragmentRoot != null) {
			fTargetPkgFragmentRoot= targetPkgFragmentRoot;
		} else if (fPackageFragmentRoots != null && fPackageFragmentRoots.length > 0) {
			fTargetPkgFragmentRoot= fPackageFragmentRoots[0];
		}
	}

	@Override
	public void addPages() {
		super.addPages();
		if (fPage == null) {
			fPage= new NewModuleInfoWizardPage();
			fPage.setWizard(this);
			fPage.init(fProject);
		}
		addPage(fPage);
	}

	@Override
	public boolean performFinish() {
		IStatus status= fPage.getModuleNameStatus();
		int severity= status.getSeverity();
		if (severity == IStatus.OK || severity == IStatus.WARNING || severity == IStatus.INFO) {
			if (fProject != null && fTargetPkgFragmentRoot != null && fPackageFragmentRoots != null && fPackageFragmentRoots.length > 0) {
				try {
					createAndOpenFile(fTargetPkgFragmentRoot, fPackageFragmentRoots);
					new Job(Messages.format(NewWizardMessages.NewModuleInfoWizard_updateProject_job, this.fProject.getElementName())) {
						@Override
						protected IStatus run(IProgressMonitor monitor) {
							try {
								convertClasspathToModulePath(monitor);
							} catch (CoreException e) {
								return e.getStatus();
							}
							return Status.OK_STATUS;
						}
					}.schedule();
				} catch (CoreException e) {
					JavaPlugin.log(e);
				}
			}
		}
		return true;
	}

	private void createAndOpenFile(IPackageFragmentRoot targetPkgFragmentRoot, IPackageFragmentRoot[] packageFragmentRoots) throws CoreException {
		createModuleInfoJava(targetPkgFragmentRoot, packageFragmentRoots);

		IFile file= ((IFolder) targetPkgFragmentRoot.getCorrespondingResource()).getFile(MODULE_INFO_JAVA_FILENAME);
		if (file.exists()) {
			BasicNewResourceWizard.selectAndReveal(file, JavaPlugin.getActiveWorkbenchWindow());
			openFile(file);
		}
	}

	private void openFile(final IFile file) {
		final IWorkbenchPage activePage= JavaPlugin.getActivePage();
		if (activePage != null) {
			final Display display= getDisplay();
			if (display != null) {
				display.asyncExec(new Runnable() {
					@Override
					public void run() {
						try {
							IDE.openEditor(activePage, file, true);
						} catch (PartInitException e) {
							JavaPlugin.log(e);
						}
					}
				});
			}
		}
	}

	private Display getDisplay() {
		Display display= Display.getCurrent();
		if (display == null)
			display= Display.getDefault();
		return display;
	}

	private void createModuleInfoJava(IPackageFragmentRoot targetPkgFragmentRoot, IPackageFragmentRoot[] packageFragmentRoots) throws CoreException {
		String fileContent= getModuleInfoFileContent(packageFragmentRoots);
		IPackageFragment defaultPkg= targetPkgFragmentRoot.getPackageFragment(""); //$NON-NLS-1$
		InfoFilesUtil.createInfoJavaFile(MODULE_INFO_JAVA_FILENAME, fileContent.toString(), defaultPkg, new NullProgressMonitor());
	}

	private String getModuleInfoFileContent(IPackageFragmentRoot[] packageFragmentRoots) throws CoreException {
		HashSet<String> exportedPackages= new HashSet<>();
		for (IPackageFragmentRoot packageFragmentRoot : packageFragmentRoots) {
			for (IJavaElement child : packageFragmentRoot.getChildren()) {
				if (child instanceof IPackageFragment) {
					IPackageFragment pkgFragment= (IPackageFragment) child;
					if (!pkgFragment.isDefaultPackage() && pkgFragment.getCompilationUnits().length != 0) {
						exportedPackages.add(pkgFragment.getElementName());
					}
				}
			}
		}

		String[] requiredModules= JavaCore.getReferencedModules(fProject);
		String moduleName= fPage.getModuleNameText();
		StringBuilder fileContent= new StringBuilder();
		fileContent.append("module "); //$NON-NLS-1$
		fileContent.append(moduleName);
		fileContent.append(" {"); //$NON-NLS-1$

		for (String exportedPkg : exportedPackages) {
			fileContent.append("exports "); //$NON-NLS-1$
			fileContent.append(exportedPkg);
			fileContent.append(";"); //$NON-NLS-1$
		}

		for (String requiredModule : requiredModules) {
			fileContent.append("requires "); //$NON-NLS-1$
			fileContent.append(requiredModule);
			fileContent.append(';');
		}

		fileContent.append('}');

		return fileContent.toString();
	}

	private void convertClasspathToModulePath(IProgressMonitor monitor) throws JavaModelException {
		boolean changed= false;
		IClasspathEntry[] rawClasspath= this.fProject.getRawClasspath();
		for (int i= 0; i < rawClasspath.length; i++) {
			IClasspathEntry entry= rawClasspath[i];
			switch (entry.getEntryKind()) {
				case IClasspathEntry.CPE_LIBRARY:
				case IClasspathEntry.CPE_PROJECT:
					IClasspathAttribute[] newAttributes= addModuleAttributeIfNeeded(entry.getExtraAttributes());
					if (newAttributes != null) {
						rawClasspath[i]= addAttributes(entry, newAttributes);
						changed= true;
					}
					break;
				default:
					// other kinds are not handled
			}
		}
		if (changed) {
			this.fProject.setRawClasspath(rawClasspath, monitor);
		}
	}

	private IClasspathAttribute[] addModuleAttributeIfNeeded(IClasspathAttribute[] extraAttributes) {
		for (int j= 0; j < extraAttributes.length; j++) {
			IClasspathAttribute classpathAttribute= extraAttributes[j];
			if (IClasspathAttribute.MODULE.equals(classpathAttribute.getName())) {
				if (TRUE.equals(classpathAttribute.getValue())) {
					return null; // no change required
				}
				extraAttributes[j]= JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, TRUE);
				return extraAttributes;
			}
		}
		extraAttributes= Arrays.copyOf(extraAttributes, extraAttributes.length+1);
		extraAttributes[extraAttributes.length-1]= JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, TRUE);
		return extraAttributes;
	}

	private IClasspathEntry addAttributes(IClasspathEntry entry, IClasspathAttribute[] extraAttributes) {
		switch (entry.getEntryKind()) {
			case IClasspathEntry.CPE_LIBRARY:
				return JavaCore.newLibraryEntry(entry.getPath(), entry.getSourceAttachmentPath(),
						entry.getSourceAttachmentRootPath(), entry.getAccessRules(), extraAttributes, entry.isExported());
			case IClasspathEntry.CPE_PROJECT:
				return JavaCore.newProjectEntry(entry.getPath(), entry.getAccessRules(), entry.combineAccessRules(),
						extraAttributes, entry.isExported());
			default:
				return entry; // other kinds are not handled
		}
	}

	@Override
	public void init(IWorkbench workbench, IStructuredSelection selection) {
		//do nothing
	}

}
