/*******************************************************************************
 * Copyright (c) 2000, 2016 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.releng.tools;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

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.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.team.core.synchronize.SyncInfoSet;
import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.internal.texteditor.SWTUtil;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;


public class BuildNotesPage extends WizardPage {

	private static final String FOLDER_BIN = "bin"; //$NON-NLS-1$

	private static final String EXT_HTML = "html"; //$NON-NLS-1$

	private static final String BUILD_NOTES_HTML = "/build_notes.html"; //$NON-NLS-1$

	private String FILE_PATH_KEY = "BuildNotesPage.filePath"; //$NON-NLS-1$

	private String UPDATE_FILE_KEY = "BuildNotesPage.updateNotesButton"; //$NON-NLS-1$

	private Button updateNotesButton;

	private boolean updateNotesButtonChecked;

	private SyncInfoSet syncInfoSet;

	private IDialogSettings settings;

	private Text reportText;

	private Map<Integer, String> bugSummaryMap;

	private boolean validPath;

	private Text filePath;

	private Button browse;

	private IFile iFile;

	protected BuildNotesPage(String pageName, String title,
			IDialogSettings settings, ImageDescriptor image) {
		super(pageName, title, image);
		this.settings = settings;
	}

	@Override
	public void createControl(Composite parent) {
		GridData data = new GridData(GridData.FILL_BOTH);
		Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayout(new GridLayout(3, false));
		composite.setLayoutData(data);

		data = new GridData(GridData.FILL_HORIZONTAL);
		data.horizontalSpan = 3;
		updateNotesButton = new Button(composite, SWT.CHECK);
		updateNotesButton.setText(Messages.getString("BuildNotesPage.2")); //$NON-NLS-1$
		updateNotesButton.setLayoutData(data);
		updateNotesButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				updateNotesButtonChecked = updateNotesButton.getSelection();
				if (updateNotesButtonChecked) {
					filePath.setEnabled(true);
					filePath.setText(filePath.getText());
					browse.setEnabled(true);
				} else {
					filePath.setEnabled(false);
					setErrorMessage(null);
					browse.setEnabled(false);
				}
				updateButtons();
			}
		});

		Label label = new Label(composite, SWT.LEFT);
		label.setText(Messages.getString("BuildNotesPage.3")); //$NON-NLS-1$

		data = new GridData(GridData.FILL_HORIZONTAL);
		filePath = new Text(composite, SWT.BORDER);
		filePath.setLayoutData(data);
		filePath.addModifyListener(e -> {
			Path path = new Path(filePath.getText());
			validPath = false;
			if (!path.isEmpty()) {
				IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
				if (path.isValidPath(filePath.getText())
						&& file.getParent().exists()) {
					if (path.getFileExtension().equals(EXT_HTML)) {
						setErrorMessage(null);
						validPath = true;
						iFile = file;
					} else {
						setErrorMessage(Messages
								.getString("BuildNotesPage.5")); //$NON-NLS-1$
					}
				} else {
					setErrorMessage(Messages.getString("BuildNotesPage.6")); //$NON-NLS-1$
				}
			} else {
				// path is empty
				setErrorMessage(Messages.getString("BuildNotesPage.7")); //$NON-NLS-1$
			}
			updateButtons();
		});

		browse = new Button(composite, SWT.PUSH);
		browse.setText(Messages.getString("BuildNotesPage.8")); //$NON-NLS-1$
		browse.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				IResource iResource = buildNotesFileDialog();
				if (iResource instanceof IFile) {
					IFile iFile = (IFile) iResource;
					filePath.setText(iFile.getFullPath().toString());
				} else if (iResource instanceof IFolder) {
					IFolder iFolder = (IFolder) iResource;
					filePath.setText(iFolder.getFullPath().toString()
							+ BUILD_NOTES_HTML);
				} else if (iResource instanceof IProject) {
					IProject iProject = (IProject) iResource;
					filePath.setText(iProject.getFullPath().toString()
							+ BUILD_NOTES_HTML);
				}
			}
		});
		SWTUtil.setButtonDimensionHint(browse);

		data = new GridData(GridData.FILL_BOTH);
		data.horizontalSpan = 3;
		reportText = new Text(composite, SWT.READ_ONLY | SWT.MULTI | SWT.BORDER
				| SWT.WRAP | SWT.V_SCROLL);
		reportText.setLayoutData(data);

		initialize();
		setControl(composite);
	}

	private void initialize() {
		initSelections();
	}

	/*
	 * initialize the controls on the page
	 */
	private void initSelections() {
		if (settings == null || settings.get(UPDATE_FILE_KEY) == null
				|| settings.get(FILE_PATH_KEY) == null) {
			updateNotesButton.setSelection(false);
			updateNotesButtonChecked = false;
			browse.setEnabled(false);
			filePath.setEnabled(false);
			return;
		} else {
			boolean b = settings.getBoolean(UPDATE_FILE_KEY);
			updateNotesButton.setSelection(b);
			updateNotesButtonChecked = b;
			filePath.setText(settings.get(FILE_PATH_KEY));
			browse.setEnabled(true);
			filePath.setEnabled(true);
		}
	}

	/*
	 * enable or disable wizard buttons
	 */
	public void updateButtons() {
		if (isUpdateNotesButtonChecked() && !getValidPath()) {
			setPageComplete(false);
		} else {
			setPageComplete(true);
		}
	}

	/*
	 * if file doesn't already exist, prepare new one otherwise call method to
	 * write to existing file
	 */
	public void updateNotesFile() {
		if (bugSummaryMap != null && !filePath.isDisposed()) {
			Path path = new Path(filePath.getText());
			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
			final IFile file = root.getFile(path);
			if (file.exists()) {
				writeUpdate(file);
			} else {
				if (file.getParent().exists()) {
					try {
						getContainer().run(true, true, monitor -> {
							monitor.beginTask(Messages.getString("BuildNotesPage.11"), //$NON-NLS-1$
									100);
							StringBuffer buffer = new StringBuffer();
							buffer.append("<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\">\n");
							buffer.append("<html>\n\n");
							buffer.append("<head>\n");
							buffer.append(
									"   <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n");
							buffer.append("   <meta name=\"Build\" content=\"Build\">\n");
							buffer.append(
									"   <title>Eclipse Platform Release Notes (3.3) - JFace and Workbench</title>\n");
							buffer.append("</head>\n\n");
							buffer.append("<body>\n\n");
							buffer.append("<h1>Eclipse Platform Build Notes (3.3)<br>\n");
							buffer.append("JFace and Workbench</h1>");

							try (ByteArrayInputStream c = new ByteArrayInputStream(buffer.toString().getBytes())) {
								try {
									file.create(c, true, monitor);
								} catch (CoreException e1) {
									CVSUIPlugin.openError(getShell(), null, null, e1);
								}
							} catch (IOException e2) {
								CVSUIPlugin.openError(getShell(), null, null, e2);
							}
							monitor.done();
						});
					} catch (InvocationTargetException e) {
						CVSUIPlugin.openError(getShell(), null, null, e);
					} catch (InterruptedException e) {
						CVSUIPlugin.openError(getShell(), null, null, e);
					}
					writeUpdate(file);
				}
			}
		}
	}

	/*
	 * write update to build notes file
	 */
	public void writeUpdate(final IFile file) {
		BufferedInputStream originalContents = null;
		try {
			originalContents = new BufferedInputStream(file.getContents());
			final StringBuffer buffer = new StringBuffer();

			int character;
			while ((character = originalContents.read()) != -1) {
				buffer.append((char) character);
			}

			String marker = "</h1>";
			SimpleDateFormat formatter = new SimpleDateFormat(
					"MMMM dd, yyyy, h:mm a");
			Date currentTime = new Date();
			String dateString = formatter.format(currentTime);
			dateString = dateString.replaceAll("AM", "a.m.");
			dateString = dateString.replaceAll("PM", "p.m.");

			int index = buffer.indexOf(marker) + marker.length();
			if (index != -1) {
				StringBuffer insertBuffer = new StringBuffer();
				insertBuffer.append("\n<p>Integration Build (" + dateString
						+ ")</p>\n");
				insertBuffer.append("  <p>Problem reports updated</p>\n");
				insertBuffer.append("  <p>\n");

				Iterator<Map.Entry<Integer, String>> i = bugSummaryMap.entrySet().iterator();
				while (i.hasNext()) {
					Map.Entry<Integer, String> entry = i.next();
					Integer bug = entry.getKey();
					String summary = entry.getValue();
					insertBuffer
							.append("<a href=\"https://bugs.eclipse.org/bugs/show_bug.cgi?id=");
					insertBuffer.append(bug);
					insertBuffer.append("\">Bug ");
					insertBuffer.append(bug);
					insertBuffer.append("</a. ");
					insertBuffer.append(summary + "<br>\n");
				}
				insertBuffer.append("  </p>");
				buffer.insert(index, "\n" + insertBuffer.toString());

				try {
					getContainer().run(true, true, monitor -> {
						monitor.beginTask(Messages.getString("BuildNotesPage.38"), 100); //$NON-NLS-1$
						ByteArrayInputStream c = new ByteArrayInputStream(buffer.toString().getBytes());
						try {
							file.setContents(c, true, true, monitor);
							c.close();
						} catch (CoreException e1) {
							CVSUIPlugin.openError(getShell(), null, null, e1);
						} catch (IOException e2) {
							CVSUIPlugin.openError(getShell(), null, null, e2);
						}
						monitor.done();
					});
				} catch (InvocationTargetException e) {
					CVSUIPlugin.openError(getShell(), null, null, e);
				} catch (InterruptedException e) {
					CVSUIPlugin.openError(getShell(), null, null, e);
				}
			}
		} catch (IOException e) {
			CVSUIPlugin.openError(getShell(), null, null, e);
		} catch (CoreException e) {
			CVSUIPlugin.openError(getShell(), null, null, e);
		}
	}

	@Override
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		if (visible) {
			reportText.setText("");
			GetBugsOperation getBugsOperation = new GetBugsOperation(
					(ReleaseWizard) getWizard(), syncInfoSet);
			getBugsOperation.run(this);
			if (bugSummaryMap != null) {
				String tempText = outputReport();
				if (tempText != null) {
					reportText.setText(tempText);
				}
			}
		}
	}

	public IResource buildNotesFileDialog() {
		ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(
				getShell(), new WorkbenchLabelProvider(),
				new WorkbenchContentProvider());

		// filter for .html files only and exclude bin folders
		dialog.addFilter(new ViewerFilter() {
			@Override
			public boolean select(Viewer viewer, Object parentElement,
					Object element) {
				if (element instanceof IFile) {
					IFile file = (IFile) element;
					IPath path = file.getFullPath();
					if (path.getFileExtension().equals(EXT_HTML)) {
						return true;
					}
				} else if (element instanceof IFolder) {
					IFolder folder = (IFolder) element;
					if (folder.getName().equals(FOLDER_BIN)) {
						return false;
					}
					return true;
				} else if (element instanceof IProject) {
					return true;
				}
				return false;
			}
		});

		dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
		dialog.setAllowMultiple(false);
		dialog.setTitle(Messages.getString("BuildNotesPage.42")); //$NON-NLS-1$
		dialog.setMessage(Messages.getString("BuildNotesPage.43")); //$NON-NLS-1$
		if (dialog.open() == Window.OK) {
			Object[] elements = dialog.getResult();
			if (elements != null && elements.length > 0) {
				if (elements[0] instanceof IFile) {
					IFile iFile = (IFile) elements[0];
					return iFile;
				} else if (elements[0] instanceof IFolder) {
					IFolder iFolder = (IFolder) elements[0];
					return iFolder;
				} else if (elements[0] instanceof IProject) {
					IProject iProject = (IProject) elements[0];
					return iProject;
				}
			}
		}
		return null;
	}

	public boolean isUpdateNotesButtonChecked() {
		return updateNotesButtonChecked;
	}

	public void setSyncInfoSet(SyncInfoSet syncInfoSet) {
		this.syncInfoSet = syncInfoSet;
	}

	/**
	 * return string of report
	 */
	public String outputReport() {
		StringBuffer buffer = new StringBuffer();
		if (bugSummaryMap.size() < 1) {
			buffer.append("The map file has been updated.\n");
		} else {
			buffer
					.append("The map file has been updated for the following Bug changes:\n");
			Iterator<Map.Entry<Integer, String>> i = bugSummaryMap.entrySet().iterator();

			while (i.hasNext()) {
				Map.Entry<Integer, String> entry = i.next();
				Integer bug = entry.getKey();
				String summary = entry.getValue();
				buffer.append("+ Bug " + bug + ". " + summary + "\n");
			}
		}
		buffer.append("\nThe following projects have changed:\n");
		IProject[] iProjects = ((ReleaseWizard) getWizard())
				.getSelectedProjects();
		for (int j = 0; j < iProjects.length; j++) {
			buffer.append(iProjects[j].getName() + "\n");
		}
		return buffer.toString();
	}

	public void setMap(Map<Integer, String> map) {
		this.bugSummaryMap = map;
	}

	public boolean getValidPath() {
		return validPath;
	}

	public IFile getIFile() {
		return iFile;
	}

	public void saveSettings() {
		settings.put(UPDATE_FILE_KEY, updateNotesButtonChecked);
		settings.put(FILE_PATH_KEY, filePath.getText());
	}
}
