/*=============================================================================#
 # Copyright (c) 2012, 2021 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.internal.r.ui.pkgmanager;

import java.lang.reflect.InvocationTargetException;
import java.util.Collections;

import org.eclipse.core.databinding.UpdateValueStrategy;
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.databinding.validation.ValidationStatus;
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.jface.databinding.viewers.typed.ViewerProperties;
import org.eclipse.jface.databinding.wizard.WizardPageSupport;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.operation.IRunnableWithProgress;
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.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.ts.core.Tool;

import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.workbench.ResourceInputComposite;

import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.r.core.pkgmanager.IRPkgData;
import org.eclipse.statet.r.core.pkgmanager.IRPkgManager;
import org.eclipse.statet.r.core.pkgmanager.RPkgAction;
import org.eclipse.statet.r.core.pkgmanager.RPkgUtils;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.rj.renv.core.RLibLocation;
import org.eclipse.statet.rj.renv.core.RPkgType;
import org.eclipse.statet.rj.renv.runtime.RuntimeRLibPaths;


public class InstallPkgFileWizard extends Wizard {
	
	
	class Page extends WizardPage {
		
		
		private static final String FILE_HISTORY= "RPkgFile.history"; //$NON-NLS-1$
		
		
		private final IObservableValue<String> fileValue;
		private final IObservableValue<RPkgType> typeValue;
		private final IObservableValue<RLibLocation> targetValue;
		
		private ResourceInputComposite fileControl;
		private Label typeControl;
		private RLibrarySelectionComposite targetControl;
		
		
		public Page() {
			super("InstallPkgFilePage"); //$NON-NLS-1$
			
			setTitle("Install R Package from File");
			setDescription("Select the package file and target location.");
			
			final Realm realm= Realm.getDefault();
			this.fileValue= new WritableValue<>(realm, "", String.class); //$NON-NLS-1$
			this.typeValue= new WritableValue<>(realm, null, RPkgType.class);
			this.targetValue= new WritableValue<>(realm, null, RLibLocation.class);
		}
		
		
		@Override
		public void createControl(final Composite parent) {
			initializeDialogUnits(parent);
			
			final Composite composite= new Composite(parent, SWT.NONE);
			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
			composite.setLayout(LayoutUtils.newContentGrid(1));
			
			this.fileControl= new ResourceInputComposite(composite, 
					ResourceInputComposite.STYLE_COMBO | ResourceInputComposite.STYLE_LABEL,
					ResourceInputComposite.MODE_FILE | ResourceInputComposite.MODE_OPEN, 
					"Package &file");
			
			this.fileControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
			this.fileControl.setHistory(getDialogSettings().getArray(FILE_HISTORY));
			
			this.typeControl= new Label(composite, SWT.NONE);
			this.typeControl.setText("Type: ");
			this.typeControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
			
			final RuntimeRLibPaths rLibPaths= InstallPkgFileWizard.this.pkgManager.getRLibPaths();
			{	final Group group= new Group(composite, SWT.NONE);
				group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
				group.setText("Target Library:");
				group.setLayout(LayoutUtils.newGroupGrid(1));
				
				this.targetControl= new RLibrarySelectionComposite(group);
				this.targetControl.setLayoutData(this.targetControl.createGD());
				this.targetControl.getValidator().setWritable(true);
				this.targetControl.setInput(rLibPaths);
			}
			
			Dialog.applyDialogFont(composite);
			setControl(composite);
			
			final DataBindingSupport databinding= new DataBindingSupport(composite);
			addBindings(databinding);
			
			validateType();
			this.targetValue.setValue(RPkgUtils.getDefaultInstallLocation(rLibPaths));
			WizardPageSupport.create(this, databinding.getContext());
		}
		
		protected void addBindings(final DataBindingSupport databinding) {
			this.fileControl.getValidator().setOnNotLocal(IStatus.OK);
			this.fileControl.getValidator().setFileStoreValidator((final IFileStore store) -> {
						if (store.getName().indexOf('_') < 0
								|| RPkgUtils.getPkgType(store.getName(), InstallPkgFileWizard.this.pkgManager.getRPlatform()) == null ) {
							return ValidationStatus.error("File name must follow the pattern '<package_name>_<version>.<ext>'.");
						}
						validateType();
						return ValidationStatus.ok();
					});
			databinding.getContext().bindValue(
					this.fileControl.getObservable(),
					this.fileValue,
					new UpdateValueStrategy<String, String>()
							.setAfterGetValidator(this.fileControl.getValidator()),
					null );
			
			this.fileControl.getTextControl().addListener(SWT.Modify, new Listener() {
				@Override
				public void handleEvent(final Event event) {
					validateType();
				}
			});
			
			databinding.getContext().bindValue(
					ViewerProperties.singleSelection(Object.class)
							.observe(this.targetControl.getSelectionViewer()),
					this.targetValue,
					new UpdateValueStrategy<Object, RLibLocation>()
							.setAfterGetValidator(this.targetControl.getValidator()),
					null );
		}
		
		void validateType() {
			RPkgType type= null;
			final IFileStore store= this.fileControl.getResourceAsFileStore();
			if (store != null) {
				type= RPkgUtils.getPkgType(store.getName(), InstallPkgFileWizard.this.pkgManager.getRPlatform());
			}
			String text= "Type: ";
			if (type != null) {
				text+= type.getLabel() +
						" (" + RPkgUtils.getPkgTypeInstallKey(InstallPkgFileWizard.this.pkgManager.getRPlatform(), type) + ")";
			}
			this.typeControl.setText(text);
			this.typeValue.setValue(type);
		}
		
		
		public IFileStore getFile() {
			return this.fileControl.getResourceAsFileStore();
		}
		
		public RPkgType getType() {
			return this.typeValue.getValue();
		}
		
		public RLibLocation getTargetLocation() {
			return this.targetValue.getValue();
		}
		
		public void saveSettings() {
			final IDialogSettings settings= getDialogSettings();
			DialogUtils.saveHistorySettings(settings, FILE_HISTORY, this.fileValue.getValue());
		}
		
	}
	
	
	private final Tool rTool;
	
	private final IRPkgManager.Ext pkgManager;
	
	private Page page;
	
	
	public InstallPkgFileWizard(final Tool rTool, final IRPkgManager.Ext manager) {
		this.rTool= rTool;
		this.pkgManager= manager;
		
		setWindowTitle("R Package Manager");
		setNeedsProgressMonitor(true);
		
		setDialogSettings(DialogUtils.getDialogSettings(RUIPlugin.getInstance(), "pkgmanager/InstallPkgFileWizard")); //$NON-NLS-1$
	}
	
	@Override
	public void addPages() {
		this.page= new Page();
		addPage(this.page);
	}
	
	@Override
	public boolean performFinish() {
		this.page.saveSettings();
		
		final IFileStore store= this.page.getFile();
		final RLibLocation location= this.page.getTargetLocation();
		try {
			getContainer().run(true, true, new IRunnableWithProgress() {
				@Override
				public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
					try {
						final IRPkgData pkgData= InstallPkgFileWizard.this.pkgManager.addToCache(store, monitor);
						final RPkgAction action= new RPkgAction.Install(pkgData, location, null);
						InstallPkgFileWizard.this.pkgManager.perform(InstallPkgFileWizard.this.rTool,
								Collections.singletonList(action) );
					}
					catch (final CoreException e) {
						throw new InvocationTargetException(e);
					}
				}
			});
		}
		catch (final InvocationTargetException e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID,
					"An error occurred when preparing the R package installation from file.", e.getCause()));
		}
		catch (final InterruptedException e) {
		}
		return true;
	}
	
}
