/*=============================================================================#
 # Copyright (c) 2009, 2019 Stephan Wahlbrink 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, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.nico.ui.util;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.util.EnumSet;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.wizard.WizardPageSupport;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.console.TextConsoleViewer;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport;
import org.eclipse.statet.ecommons.io.FileUtil;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.ui.util.VariableFilterUtils;

import org.eclipse.statet.internal.nico.ui.NicoUIPlugin;
import org.eclipse.statet.nico.core.runtime.SubmitType;
import org.eclipse.statet.nico.core.runtime.ToolProcess;
import org.eclipse.statet.nico.core.util.TrackWriter;
import org.eclipse.statet.nico.core.util.TrackingConfiguration;
import org.eclipse.statet.nico.ui.NicoUI;
import org.eclipse.statet.nico.ui.console.NIConsoleOutputStream;
import org.eclipse.statet.nico.ui.console.NIConsolePage;


/**
 * Wizard to export the console output
 */
public class ExportConsoleOutputWizard extends Wizard {
	
	
	private static final String FILE_HISTORY_SETTINGSKEY= "FileLocation_history";
	
	
	protected static class ConfigurationPage extends WizardPage {
		
		
		private final NIConsolePage consolePage;
		
		private final TrackingConfiguration config;
		private final IObservableValue<Boolean> openValue;
		
		private TrackingConfigurationComposite configControl;
		private Button openControl;
		
		private DataBindingSupport dataBinding;
		
		
		
		public ConfigurationPage(final NIConsolePage page, final TrackingConfiguration config, final boolean selectionMode) {
			super("ConfigureConsoleExportPage"); //$NON-NLS-1$
			this.consolePage= page;
			setTitle(selectionMode ? "Export Selected Output" : "Export Current Output");
			setDescription("Select the content to export and the destination file.");
			
			this.config= config;
			
			final Realm realm= Realm.getDefault();
			this.openValue= new WritableValue<>(realm, false, Boolean.class);
		}
		
		@Override
		public void createControl(final Composite parent) {
			initializeDialogUnits(parent);
			
			final Composite composite= new Composite(parent, SWT.NONE);
			composite.setLayout(LayoutUtils.newContentGrid(1));
			
			this.configControl= createTrackingControl(composite);
			this.configControl.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
			
			this.configControl.getPathInput().getValidator().setOnLateResolve(IStatus.ERROR);
			this.configControl.getPathInput().setShowInsertVariable(true,
					VariableFilterUtils.DEFAULT_NON_ITERACTIVE_FILTERS,
					this.consolePage.getTool().getWorkspaceData().getStringVariables() );
			this.configControl.setInput(this.config);
			
			final Composite additionalOptions= createAdditionalOptions(composite);
			additionalOptions.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
			
			LayoutUtils.addSmallFiller(composite, true);
			final ToolInfoGroup info= new ToolInfoGroup(composite, this.consolePage.getTool());
			info.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
			
			Dialog.applyDialogFont(composite);
			setControl(composite);
			
			this.configControl.getPathInput().setHistory(getDialogSettings().getArray(FILE_HISTORY_SETTINGSKEY));
			this.dataBinding= new DataBindingSupport(composite);
			addBindings(this.dataBinding);
			WizardPageSupport.create(this, this.dataBinding.getContext());
		}
		
		protected TrackingConfigurationComposite createTrackingControl(final Composite parent) {
			return new TrackingConfigurationComposite(parent) {
				@Override
				protected boolean enableFullMode() {
					return false;
				}
				@Override
				protected boolean enableFilePathAsCombo() {
					return true;
				}
				@Override
				protected EnumSet<SubmitType> getEditableSubmitTypes() {
					return EnumSet.of(SubmitType.OTHER);
				}
			};
		}
		
		protected Composite createAdditionalOptions(final Composite parent) {
			final Group composite= new Group(parent, SWT.NONE);
			composite.setText("Actions:");
			composite.setLayout(LayoutUtils.newGroupGrid(1));
			
			this.openControl= new Button(composite, SWT.CHECK);
			this.openControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
			this.openControl.setText("Open in &Editor");
			
			return composite;
		}
		
		protected void addBindings(final DataBindingSupport db) {
			this.configControl.addBindings(db);
			
			db.getContext().bindValue(
					WidgetProperties.selection().observe(this.openControl),
					this.openValue );
		}
		
		public boolean getOpenInEditor() {
			return this.openValue.getValue().booleanValue();
		}
		
		protected void saveSettings() {
			final IDialogSettings settings= getDialogSettings();
			DialogUtils.saveHistorySettings(settings, FILE_HISTORY_SETTINGSKEY, this.config.getFilePath());
		}
		
	}
	
	
	private TrackingConfiguration config;
	private final int selectionLength;
	
	private final NIConsolePage consolePage;
	
	private ConfigurationPage configPage;
	
	
	public ExportConsoleOutputWizard(final NIConsolePage consolePage) {
		this.consolePage= consolePage;
		this.selectionLength= ((ITextSelection) consolePage.getOutputViewer().getSelection()).getLength();
		
		setWindowTitle("Export Console Output");
		setNeedsProgressMonitor(true);
		
		setDialogSettings(DialogUtils.getDialogSettings(NicoUIPlugin.getInstance(), "tools/ExportConsoleOutputWizard"));
	}
	
	protected TrackingConfiguration createTrackingConfiguration() {
		final TrackingConfiguration config= new TrackingConfiguration(""); //$NON-NLS-1$
		config.getSubmitTypes().remove(SubmitType.OTHER);
		return config;
	}
	
	@Override
	public void addPages() {
		this.config= createTrackingConfiguration();
		this.configPage= new ConfigurationPage(this.consolePage, this.config, this.selectionLength > 0);
		addPage(this.configPage);
	}
	
	
	@Override
	public boolean performFinish() {
		this.configPage.saveSettings();
		final boolean openInEditor= this.configPage.getOpenInEditor();
		try {
			getContainer().run(true, true, new IRunnableWithProgress() {
				@Override
				public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
					final SubMonitor m= SubMonitor.convert(monitor, "Export Output", 100);
					final TextConsoleViewer outputViewer= ExportConsoleOutputWizard.this.consolePage.getOutputViewer();
					final AbstractDocument document= (AbstractDocument) outputViewer.getDocument();
					
					final IJobManager jobManager= Job.getJobManager();
					final ISchedulingRule schedulingRule= ExportConsoleOutputWizard.this.consolePage.getConsole().getSchedulingRule();
					jobManager.beginRule(schedulingRule, m.newChild(1));
					try {
						if (ExportConsoleOutputWizard.this.selectionLength > 0) {
							final AtomicReference<ITextSelection> currentSelection= new AtomicReference<>();
							getShell().getDisplay().syncExec(new Runnable() {
								@Override
								public void run() {
									final ITextSelection selection= (ITextSelection) outputViewer.getSelection();
									if (selection.getLength() != ExportConsoleOutputWizard.this.selectionLength) {
										final boolean continueExport= MessageDialog.openQuestion(getShell(), "Export Output",
												"The selection is changed due to updates in the console. Do you want to continue nevertheless?");
										if (!continueExport) {
											return;
										}
									}
									currentSelection.set(selection);
								}
							});
							final ITextSelection selection= currentSelection.get();
							if (selection == null) {
								return;
							}
							
							export(document, selection.getOffset(), selection.getLength(), openInEditor, m);
						}
						else {
							export(document, 0, document.getLength(), openInEditor, m);
						}
					}
					finally {
						jobManager.endRule(schedulingRule);
					}
				}
			});
		}
		catch (final InvocationTargetException e) {
			final Throwable cause= e.getCause();
			StatusManager.getManager().handle(new Status(IStatus.ERROR, NicoUI.BUNDLE_ID, -1,
					"An error occurred when exporting console output to file.", cause),
					StatusManager.LOG | StatusManager.SHOW);
			return !(cause instanceof CoreException || cause instanceof IOException);
		}
		catch (final InterruptedException e) {
		}
		return true;
	}
	
	private void export(final AbstractDocument document, final int offset, final int length, final boolean openInEditor,
			final SubMonitor m) throws InvocationTargetException {
		m.setWorkRemaining(1 + 20);
		
		OutputStream outputStream= null;
		Writer outputWriter= null;
		try {
			String filePath= this.config.getFilePath();
			filePath= TrackWriter.resolveVariables(filePath, this.consolePage.getTool().getWorkspaceData());
			final IFileStore fileStore= FileUtil.getFileStore(filePath);
			
			outputStream= fileStore.openOutputStream(this.config.getFileMode(), m.newChild(1));
			if (fileStore.fetchInfo().getLength() <= 0L) {
				FileUtil.prepareTextOutput(outputStream, this.config.getFileEncoding());
			}
			outputWriter= new BufferedWriter(new OutputStreamWriter(outputStream, this.config.getFileEncoding()));
			
			if (this.config.getPrependTimestamp()) {
				final ToolProcess process= this.consolePage.getConsole().getProcess();
				outputWriter.append(process.createTimestampComment(process.getConnectionTimestamp()));
			}
			
			if (this.config.getTrackStreamInfo() && this.config.getTrackStreamInput()
					&& this.config.getTrackStreamOutput() && !this.config.getTrackStreamOutputTruncate()
					&& this.config.getSubmitTypes().contains(SubmitType.OTHER) ) {
				int pOffset= offset;
				int pLength= length;
				while (pLength > 0) {
					final int currentLength= Math.min(pLength, 32768);
					outputWriter.append(document.get(pOffset, currentLength));
					pOffset+= currentLength;
					pLength-= currentLength;
				}
			}
			else {
				final ITypedRegion[] partitions= document.getDocumentPartitioner().computePartitioning(offset, length);
				final SubMonitor m1= m.newChild(20);
				int workRemaining= partitions.length;
				for (final ITypedRegion partition : partitions) {
					m1.setWorkRemaining(workRemaining--);
					final String type= partition.getType();
					String text2= null;
					
					if (type == null) {
						continue;
					}
					
					boolean truncate= false;
					if (type == NIConsoleOutputStream.INFO_STREAM_ID) {
						if (!this.config.getTrackStreamInfo()) {
							continue;
						}
					}
					else if (type == NIConsoleOutputStream.OTHER_TASKS_INFO_STREAM_ID) {
						if (!this.config.getTrackStreamInfo()
								|| !this.config.getSubmitTypes().contains(SubmitType.OTHER)) {
							continue;
						}
					}
					else if (type == NIConsoleOutputStream.STD_INPUT_STREAM_ID) {
						if (!this.config.getTrackStreamInput()) {
							continue;
						}
					}
					else if (type == NIConsoleOutputStream.OTHER_TASKS_STD_INPUT_STREAM_ID) {
						if (!this.config.getTrackStreamInput()
								|| !this.config.getSubmitTypes().contains(SubmitType.OTHER)) {
							continue;
						}
					}
					else if (type == NIConsoleOutputStream.STD_OUTPUT_STREAM_ID) {
						if (!this.config.getTrackStreamOutput()) {
							continue;
						}
						truncate= this.config.getTrackStreamOutputTruncate();
					}
					else if (type == NIConsoleOutputStream.OTHER_TASKS_INFO_STREAM_ID) {
						if (!this.config.getTrackStreamOutput()
								|| !this.config.getSubmitTypes().contains(SubmitType.OTHER)) {
							continue;
						}
						truncate= this.config.getTrackStreamOutputTruncate();
					}
					else if (type == NIConsoleOutputStream.STD_ERROR_STREAM_ID) {
						if (!this.config.getTrackStreamOutput()) {
							continue;
						}
					}
					else if (type == NIConsoleOutputStream.OTHER_TASKS_STD_ERROR_STREAM_ID) {
						if (!this.config.getTrackStreamOutput()
								|| !this.config.getSubmitTypes().contains(SubmitType.OTHER)) {
							continue;
						}
					}
					else {
					}
					
					int pOffset= Math.max(offset, partition.getOffset());
					int pLength= Math.min(offset+length, partition.getOffset()+partition.getLength()) - pOffset;
					if (truncate) {
						final int firstLine= document.getLineOfOffset(pOffset);
						final int lastLine= document.getLineOfOffset(pOffset+pLength);
						if (lastLine - firstLine + 1 > this.config.getTrackStreamOutputTruncateLines()) {
							pLength= document.getLineOffset(firstLine + this.config.getTrackStreamOutputTruncateLines()) - pOffset;
							text2= "[...] (truncated)\n\n";
						}
					}
					
					while (pLength > 0) {
						final int currentLength= Math.min(pLength, 32768);
						outputWriter.append(document.get(pOffset, currentLength));
						pOffset+= currentLength;
						pLength-= currentLength;
					}
					if (text2 != null) {
						outputWriter.append(text2);
					}
				}
			}
			
			outputWriter.close();
			outputWriter= null;
			
			if (openInEditor) {
				UIAccess.getDisplay().asyncExec(new Runnable() {
					@Override
					public void run() {
						OpenTrackingFilesContributionItem.open("export", fileStore);
					}
				});
			}
		}
		catch (final Exception e) {
			throw new InvocationTargetException(e);
		}
		finally {
			if (outputWriter != null) {
				try {
					outputWriter.close();
				} catch (final IOException ignore) {}
			}
			else if (outputStream != null) {
				try {
					outputStream.close();
				} catch (final IOException ignore) {}
			}
		}
	}
	
}
