/*******************************************************************************
 * Copyright (c) 2007, 2018 Alphonse Van Assche and others.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Alphonse Van Assche - initial API and implementation
 *    Red Hat Inc. - ongoging maintenance
 *******************************************************************************/

package org.eclipse.linuxtools.rpm.ui.editor.wizards;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.linuxtools.internal.rpm.ui.editor.Activator;
import org.eclipse.linuxtools.internal.rpm.ui.editor.SpecfileLog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ContainerSelectionDialog;

public class SpecfileNewWizardPage extends WizardPage {

	private static final String NAME = "package_name"; //$NON-NLS-1$

	private static final String VERSION = "1.0"; //$NON-NLS-1$

	private static final String SUMMARY = "Summary of the package"; //$NON-NLS-1$

	private static final String GROUP = "Amusements/Games"; //$NON-NLS-1$

	private static final String LICENSE = "GPL"; //$NON-NLS-1$

	private static final String URL = "http://"; //$NON-NLS-1$

	private static final String SOURCE0 = "archive_name-%{version}"; //$NON-NLS-1$

	private Text projectText;

	private Text nameText;

	private Text versionText;

	private Text summaryText;

	private Combo groupCombo;

	private Text licenseText;

	private Text urlText;

	private Text source0Text;

	private GridData gd;

	private ISelection selection;

	private String selectedTemplate = "minimal"; //$NON-NLS-1$

	private String content;

	/**
	 * Constructor for SpecfileNewWizardPage.
	 *
	 * @param selection The selection to put the new spec file in.
	 */
	public SpecfileNewWizardPage(ISelection selection) {
		super("wizardPage"); //$NON-NLS-1$
		setTitle(Messages.SpecfileNewWizardPage_9);
		setDescription(Messages.SpecfileNewWizardPage_10);
		this.selection = selection;
	}

	@Override
	public void createControl(Composite parent) {
		final Composite container = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		container.setLayout(layout);
		layout.numColumns = 3;
		layout.verticalSpacing = 9;

		// Project
		Label label = new Label(container, SWT.NULL);
		label.setText(Messages.SpecfileNewWizardPage_11);
		projectText = new Text(container, SWT.BORDER | SWT.SINGLE);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		projectText.setLayoutData(gd);
		projectText.addModifyListener(e -> dialogChanged());
		Button button = new Button(container, SWT.PUSH);
		button.setText(Messages.SpecfileNewWizardPage_12);
		button.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> handleBrowse()));

		// Template to use
		label = new Label(container, SWT.NULL);
		label.setText(Messages.SpecfileNewWizardPage_13);
		Combo templateCombo = new Combo(container, SWT.NULL);
		try {
			populateTemplateCombo(templateCombo);
		} catch (CoreException e2) {
			SpecfileLog.logError(e2);
		}
		// empty label for the last row.
		label = new Label(container, SWT.NULL);
		templateCombo.addModifyListener(e -> {
			selectedTemplate = ((Combo) e.getSource()).getText();
			InputStream inputStream = runRpmdevNewSpec(selectedTemplate);
			LineNumberReader reader = new LineNumberReader(new InputStreamReader(inputStream));
			String line;
			try {
				content = ""; //$NON-NLS-1$
				setDefaultValues();
				while ((line = reader.readLine()) != null) {
					if (line.startsWith("Name:")) { //$NON-NLS-1$
						setTemplateTagValue(nameText, line);
					}
					if (line.startsWith("Version:")) { //$NON-NLS-1$
						setTemplateTagValue(versionText, line);
					}
					if (line.startsWith("Summary:")) { //$NON-NLS-1$
						setTemplateTagValue(summaryText, line);
					}
					if (line.startsWith("Group:")) { //$NON-NLS-1$
						String[] items = line.split(":", 2); //$NON-NLS-1$
						String value = items[1].trim();
						if (!value.equals("")) {//$NON-NLS-1$
							groupCombo.setText(value);
						}
					}
					if (line.startsWith("License:")) { //$NON-NLS-1$
						setTemplateTagValue(licenseText, line);
					}
					if (line.startsWith("URL:")) { //$NON-NLS-1$
						setTemplateTagValue(urlText, line);
					}
					if (line.startsWith("Source0:")) { //$NON-NLS-1$
						setTemplateTagValue(source0Text, line);
					}
					content += line + '\n';
				}
			} catch (IOException e1) {
				SpecfileLog.logError(e1);
			}
		});

		// Package Name
		nameText = setTextItem(container, Messages.SpecfileNewWizardPage_14);

		// Package Version
		versionText = setTextItem(container, Messages.SpecfileNewWizardPage_15);

		// Package Summary
		summaryText = setTextItem(container, Messages.SpecfileNewWizardPage_16);

		// Package Group
		label = new Label(container, SWT.NULL);
		label.setText(Messages.SpecfileNewWizardPage_17);
		groupCombo = new Combo(container, SWT.NULL);
		populateGroupCombo(groupCombo);
		// empty label for the last row.
		new Label(container, SWT.NULL);

		// Package License
		licenseText = setTextItem(container, Messages.SpecfileNewWizardPage_18);

		// Package URL
		urlText = setTextItem(container, Messages.SpecfileNewWizardPage_19);

		// Package Source0
		source0Text = setTextItem(container, Messages.SpecfileNewWizardPage_20);

		initialize();
		dialogChanged();
		setControl(container);
	}

	private Text setTextItem(Composite container, String textLabel) {
		Label label = new Label(container, SWT.NULL);
		label.setText(textLabel);
		Text text = new Text(container, SWT.BORDER | SWT.SINGLE);
		text.setLayoutData(gd);
		text.addModifyListener(e -> dialogChanged());
		// empty label for the last row.
		new Label(container, SWT.NULL);
		return text;
	}

	private void setTemplateTagValue(Text text, String line) {
		String[] items = line.split(":", 2); //$NON-NLS-1$
		String value = items[1].trim();
		if (!value.equals("")) { //$NON-NLS-1$
			text.setText(value);
		}
	}

	public String getProjectName() {
		return projectText.getText();
	}

	public String getFileName() {
		return nameText.getText() + ".spec"; //$NON-NLS-1$
	}

	public String getSelectedTemplate() {
		return selectedTemplate;
	}

	public String getContent() {
		InputStream inputStream = runRpmdevNewSpec(selectedTemplate);
		LineNumberReader reader = new LineNumberReader(new InputStreamReader(inputStream));
		String line;
		try {
			content = ""; //$NON-NLS-1$
			while ((line = reader.readLine()) != null) {
				if (line.startsWith("Name:")) { //$NON-NLS-1$
					line = "Name:" + "           " + nameText.getText(); //$NON-NLS-1$ //$NON-NLS-2$
				}
				if (line.startsWith("Version:")) { //$NON-NLS-1$
					line = "Version:" + "        " + versionText.getText(); //$NON-NLS-1$ //$NON-NLS-2$
				}
				if (line.startsWith("Summary:")) { //$NON-NLS-1$
					line = "Summary:" + "        " + summaryText.getText(); //$NON-NLS-1$ //$NON-NLS-2$
				}
				if (line.startsWith("Group:")) { //$NON-NLS-1$
					line = "Group:" + "          " + groupCombo.getText(); //$NON-NLS-1$ //$NON-NLS-2$
				}
				if (line.startsWith("License:")) { //$NON-NLS-1$
					line = "License:" + "        " + licenseText.getText(); //$NON-NLS-1$ //$NON-NLS-2$
				}
				if (line.startsWith("URL:")) { //$NON-NLS-1$
					line = "URL:" + "            " + urlText.getText(); //$NON-NLS-1$ //$NON-NLS-2$
				}
				if (line.startsWith("Source0:")) { //$NON-NLS-1$
					line = "Source0:" + "        " + source0Text.getText(); //$NON-NLS-1$ //$NON-NLS-2$
				}
				content += line + '\n';
			}
		} catch (IOException e1) {
			SpecfileLog.logError(e1);
		}
		return content;
	}

	/**
	 * Tests if the current workbench selection is a suitable container to use.
	 */
	private void initialize() {
		if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
			IStructuredSelection ssel = (IStructuredSelection) selection;
			if (ssel.size() > 1) {
				return;
			}
			Object obj = ssel.getFirstElement();
			if (obj instanceof IResource) {
				IContainer container;
				if (obj instanceof IContainer) {
					container = (IContainer) obj;
				} else {
					container = ((IResource) obj).getParent();
				}
				projectText.setText(container.getFullPath().toString());
			}
		}
		setDefaultValues();
	}

	/**
	 * Uses the standard container selection dialog to choose the new value for the
	 * container field.
	 */
	private void handleBrowse() {
		ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(),
				ResourcesPlugin.getWorkspace().getRoot(), false, Messages.SpecfileNewWizardPage_21);
		if (dialog.open() == Window.OK) {
			Object[] result = dialog.getResult();
			if (result.length == 1) {
				projectText.setText(((Path) result[0]).toString());
			}
		}
	}

	/**
	 * Ensures that both text fields are set.
	 */
	private void dialogChanged() {
		IResource container = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(getProjectName()));
		String fileName = getFileName();
		if (getProjectName().length() == 0) {
			updateStatus(Messages.SpecfileNewWizardPage_22);
			return;
		}
		if (container == null || (container.getType() & (IResource.PROJECT | IResource.FOLDER)) == 0) {
			updateStatus(Messages.SpecfileNewWizardPage_23);
			return;
		}
		if (!container.isAccessible()) {
			updateStatus(Messages.SpecfileNewWizardPage_24);
			return;
		}
		if (fileName.length() == 0) {
			updateStatus(Messages.SpecfileNewWizardPage_25);
			return;
		}

		/*
		 * Current RPM doc content (4.4.2): Names must not include whitespace and may
		 * include a hyphen '-' (unlike version and releasetags). Names should not
		 * include any numeric operators ('<', '>','=') as future versions of rpm may
		 * need to reserve characters other than '-'.
		 */
		String packageName = nameText.getText();
		if (packageName.indexOf(' ') != -1 || packageName.indexOf('<') != -1 || packageName.indexOf('>') != -1
				|| packageName.indexOf('=') != -1) {
			updateStatus(Messages.SpecfileNewWizardPage_26 + Messages.SpecfileNewWizardPage_27);
			return;
		}

		if (versionText.getText().indexOf("-") > -1) { //$NON-NLS-1$
			updateStatus(Messages.SpecfileNewWizardPage_28);
			return;
		}

		updateStatus(null);
	}

	protected void updateStatus(String message) {
		setErrorMessage(message);
		setPageComplete(message == null);
	}

	private void setDefaultValues() {
		nameText.setText(NAME);
		versionText.setText(VERSION);
		summaryText.setText(SUMMARY);
		groupCombo.setText(GROUP);
		licenseText.setText(LICENSE);
		urlText.setText(URL);
		source0Text.setText(SOURCE0);
	}

	private void populateTemplateCombo(Combo templateCombo) throws CoreException {
		// get a list of all files in a directory
		File dir = new File("/etc/rpmdevtools"); //$NON-NLS-1$
		String[] files = dir.list();
		if (dir.exists()) {
			String templateCSV = ""; //$NON-NLS-1$
			for (String file : files) {
				if (file.startsWith("spectemplate-")) { //$NON-NLS-1$
					templateCSV += file.split("-", 2)[1].replaceAll("\\.spec", //$NON-NLS-1$ //$NON-NLS-2$
							"") //$NON-NLS-1$
							+ ","; //$NON-NLS-1$
				}
			}
			String[] templates = templateCSV.split(","); //$NON-NLS-1$
			for (String template : templates) {
				templateCombo.add(template);
			}
			templateCombo.setText(selectedTemplate);
		} else {
			throwCoreException(Messages.SpecfileNewWizardPage_29);
		}
	}

	private void populateGroupCombo(Combo groupsCombo) {
		List<String> rpmGroups = Activator.getDefault().getRpmGroups();
		for (String rpmGroup : rpmGroups) {
			groupsCombo.add(rpmGroup);
		}
	}

	private BufferedInputStream runRpmdevNewSpec(String template) {
		BufferedInputStream in = null;
		// Here we assuming that the rpmdevtools package is installed.
		try {
			in = org.eclipse.linuxtools.rpm.core.utils.Utils.runCommandToInputStream("rpmdev-newspec", "-o", "-", "-t", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
					template);
		} catch (IOException e) {
			// FIXME: rpmdev-newspec is not in the system $PATH, what should we
			// do here?.
			SpecfileLog.logError(e);
		}
		return in;
	}

	private void throwCoreException(String message) throws CoreException {
		IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.OK, message, null);
		throw new CoreException(status);
	}

	public Text getNameText() {
		return nameText;
	}

	public Text getProjectText() {
		return projectText;
	}

	public Text getVersionText() {
		return versionText;
	}

	public Text getUrlText() {
		return urlText;
	}

	public Text getLicenseText() {
		return licenseText;
	}

	public Text getSourceText() {
		return source0Text;
	}

	public Text getSummaryText() {
		return summaryText;
	}

}