/*=============================================================================#
 # Copyright (c) 2007, 2017 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;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.ibm.icu.text.Collator;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.runtime.IStatus;
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.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImIdentitySet;

import org.eclipse.statet.ecommons.preferences.core.PreferenceAccess;
import org.eclipse.statet.ecommons.preferences.core.PreferenceSetService.ChangeEvent;
import org.eclipse.statet.ecommons.preferences.core.util.PreferenceUtils;
import org.eclipse.statet.ecommons.preferences.ui.PreferenceSetUIListener;
import org.eclipse.statet.ecommons.ui.util.LayoutUtil;

import org.eclipse.statet.internal.r.debug.ui.preferences.REnvPreferencePage;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.core.renv.IREnv;
import org.eclipse.statet.r.core.renv.IREnvConfiguration;
import org.eclipse.statet.r.core.renv.IREnvManager;
import org.eclipse.statet.r.core.renv.REnvUtils;


/**
 * Composite to choose a configured R Environment.
 */
public class REnvSelectionComposite extends Composite {
	
	
	private static final ImIdentitySet<String> PREF_QUALIFIERS= ImCollections.newIdentitySet(
			IREnvManager.PREF_QUALIFIER );
	
	
	private static final Comparator<IREnv> RENV_COMPARATOR= new Comparator<IREnv>() {
		@Override
		public int compare(final IREnv o1, final IREnv o2) {
			return Collator.getInstance().compare(o1.getName(), o2.getName());
		}
	};
	
	
	public static interface ChangeListener {
		public void settingChanged(REnvSelectionComposite source, String oldValue, String newValue,
				IREnv newREnv);
	}
	
	private class CompositeObservable extends AbstractObservableValue implements ChangeListener {
		
		public CompositeObservable(final Realm realm) {
			super(realm);
			REnvSelectionComposite.this.addChangeListener(CompositeObservable.this);
		}
		
		@Override
		public void settingChanged(final REnvSelectionComposite source, final String oldValue,
				final String newValue, final IREnv newREnv) {
			fireValueChange(Diffs.createValueDiff(oldValue, newValue));
		}
		
		@Override
		protected void doSetValue(final Object value) {
			setEncodedSetting((String) value);
		}
		
		@Override
		protected Object doGetValue() {
			return getEncodedSetting();
		}
		
		@Override
		public Object getValueType() {
			return String.class;
		}
		
		public REnvSelectionComposite getComposite() {
			return REnvSelectionComposite.this;
		}
	}
	
	private class ChooseREnvValidator implements IValidator {
		
		@Override
		public IStatus validate(final Object dummy) {
			if (REnvSelectionComposite.this.invalidPreference) {
				return ValidationStatus.error(RUIMessages.ChooseREnv_error_InvalidPreferences_message);
			}
			if (REnvSelectionComposite.this.currentREnv == null) {
				if (REnvSelectionComposite.this.enableNone) {
					return ValidationStatus.ok();
				}
				return ValidationStatus.error(RUIMessages.ChooseREnv_error_IncompleteSelection_message);
			}
			final IREnv rEnv= REnvSelectionComposite.this.currentREnv.resolve();
			if (rEnv == null
					|| (REnvSelectionComposite.this.validREnvs != null && !REnvSelectionComposite.this.validREnvs.contains(rEnv))
					|| rEnv.getConfig() == null) {
				return ValidationStatus.error(RUIMessages.ChooseREnv_error_InvalidSelection_message);
			}
			return ValidationStatus.ok();
		}
		
	}
	
	
	private final PreferenceAccess prefAccess;
	
	private final boolean enableNone;
	
	private boolean invalidPreference;
	private List<IREnv> validREnvs;
	
	private IREnv currentREnv;
	private String currentEncoded;
	private IREnv currentSpecified;
	private final CopyOnWriteIdentityListSet<ChangeListener> listeners= new CopyOnWriteIdentityListSet<>();
	
	private DataBindingContext bindindContext;
	private Binding bindings;
	
	private Button noneButton;
	private Button workbenchDefaultButton;
	private Text workbenchLabel;
	private Button specificButton;
	private Combo specificCombo;
	private Button configurationButton;
	
	
	public REnvSelectionComposite(final Composite parent) {
		this(parent, false);
	}
	
	public REnvSelectionComposite(final Composite parent, final boolean enableNone) {
		super(parent, SWT.NONE);
		this.enableNone= enableNone;
		
		this.invalidPreference= true;
		
		createControls();
		this.workbenchDefaultButton.setSelection(true);
		
		this.prefAccess= PreferenceUtils.getInstancePrefs();
		initPreferences();
		updateState(true, false);
	}
	
	
	private void initPreferences() {
		new PreferenceSetUIListener(this.prefAccess, this.specificCombo) {
			@Override
			protected void handlePreferenceChanged(final ChangeEvent event) {
				if (event.contains(IREnvManager.PREF_QUALIFIER)) {
					loadREnvironments();
				}
			}
		}.subscribe(PREF_QUALIFIERS);
		
		loadREnvironments();
	}
	
	private void createControls() {
		final Composite container= this;
		container.setLayout(LayoutUtil.createCompositeGrid(3));
		
		if (this.enableNone) {
			this.noneButton= new Button(container, SWT.RADIO);
			this.noneButton.setText(RUIMessages.ChooseREnv_None_label);
			this.noneButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
		}
		
		this.workbenchDefaultButton= new Button(container, SWT.RADIO);
		this.workbenchDefaultButton.setText(RUIMessages.ChooseREnv_WorkbenchDefault_label);
		this.workbenchDefaultButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		this.workbenchLabel= new Text(container, SWT.BORDER | SWT.LEFT | SWT.SINGLE | SWT.READ_ONLY);
		this.workbenchLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		LayoutUtil.addGDDummy(container);
		
		this.specificButton= new Button(container, SWT.RADIO);
		this.specificButton.setText(RUIMessages.ChooseREnv_Selected_label);
		this.specificButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		this.specificCombo= new Combo(container, SWT.DROP_DOWN | SWT.READ_ONLY);
		this.specificCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		
		this.configurationButton= new Button(container, SWT.PUSH);
		this.configurationButton.setText(RUIMessages.ChooseREnv_Configure_label);
		this.configurationButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		
		if (this.enableNone) {
			this.noneButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(final SelectionEvent e) {
					if (REnvSelectionComposite.this.noneButton.getSelection()) {
						REnvSelectionComposite.this.currentREnv= null;
						updateState(false, false);
					}
				}
			});
		}
		this.workbenchDefaultButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(final SelectionEvent e) {
				if (REnvSelectionComposite.this.workbenchDefaultButton.getSelection()) {
					REnvSelectionComposite.this.currentREnv= RCore.getREnvManager().getDefault();
					updateState(false, false);
				}
			}
		});
		this.specificButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(final SelectionEvent e) {
				if (REnvSelectionComposite.this.specificButton.getSelection()) {
					REnvSelectionComposite.this.currentREnv= REnvSelectionComposite.this.currentSpecified;
					updateState(false, false);
				}
			}
		});
		this.specificCombo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(final SelectionEvent event) {
				final String name= getSpecifiedName();
				if (name != null) {
					REnvSelectionComposite.this.currentREnv= RCore.getREnvManager().get(null, name);
					updateState(false, false);
				}
			}
		});
		this.configurationButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(final SelectionEvent e) {
				org.eclipse.ui.dialogs.PreferencesUtil.createPreferenceDialogOn(getShell(),
						REnvPreferencePage.PREF_PAGE_ID, new String[] { REnvPreferencePage.PREF_PAGE_ID },
						null).open();
			}
		});
	}
	
	private void loadREnvironments() {
		this.invalidPreference= true;
		final IREnvManager manager= RCore.getREnvManager();
		manager.getReadLock().lock();
		try {
			// Workbench default
			final IREnv defaultEnv= manager.getDefault();
			final List<IREnvConfiguration> list= manager.getConfigurations();
			this.validREnvs= getValidREnvs(list);
			Collections.sort(this.validREnvs, RENV_COMPARATOR);
			final String[] validNames= new String[this.validREnvs.size()];
			for (int i= 0; i < validNames.length; i++) {
				validNames[i]= this.validREnvs.get(i).getName();
			}
			this.workbenchLabel.setText(defaultEnv.getName());
			if (!list.isEmpty()) {
				this.invalidPreference= false;
			}
			// Specifics
			this.specificCombo.setItems(validNames);
			if (this.currentSpecified != null) {
				final boolean current= (this.currentREnv == this.currentSpecified);
				this.currentSpecified= manager.get(this.currentSpecified.getId(), this.currentSpecified.getName());
				if (current) {
					this.currentREnv= this.currentSpecified;
				}
			}
		}
		finally {
			manager.getReadLock().unlock();
			updateState(false, true);
		}
	}
	
	protected List<IREnv> getValidREnvs(final List<IREnvConfiguration> configurations) {
		final List<IREnv> list= new ArrayList<>(configurations.size());
		for (final IREnvConfiguration rEnvConfig : configurations) {
			if (isValid(rEnvConfig)) {
				list.add(rEnvConfig.getReference());
			}
		}
		return list;
	}
	
	protected boolean isValid(final IREnvConfiguration rEnvConfig) {
		return (!rEnvConfig.isDeleted());
	}
	
	public void setSetting(final IREnv rEnv) {
		this.currentREnv= rEnv;
		updateState(true, false);
	}
	
	public String getEncodedSetting() {
		return this.currentEncoded;
	}
	
	public void setEncodedSetting(final String encodedSetting) {
		setSetting(REnvUtils.decode(encodedSetting, RCore.getREnvManager()));
	}
	
	private String getSpecifiedName() {
		final int idx= this.specificCombo.getSelectionIndex();
		if (idx >= 0) {
			return this.specificCombo.getItem(idx);
		}
		return null;
	}
	
	public IREnv getSelection() {
		return this.currentREnv;
	}
	
	private void updateState(final boolean updateSelection, final boolean force) {
		final boolean isWorkbench= (this.currentREnv != null
				&& this.currentREnv.getId().equals(IREnv.DEFAULT_WORKBENCH_ENV_ID) );
		final boolean isSpecific= (this.currentREnv != null && !isWorkbench);
		if (updateSelection) {
			if (this.noneButton != null) {
				this.noneButton.setSelection(!isWorkbench && !isSpecific);
			}
			this.workbenchDefaultButton.setSelection(isWorkbench);
			this.specificButton.setSelection(isSpecific);
		}
		this.workbenchLabel.setEnabled(this.workbenchDefaultButton.getSelection());
		this.specificCombo.setEnabled(this.specificButton.getSelection());
		
		if (isSpecific) {
			this.currentSpecified= this.currentREnv;
		}
		if (this.currentSpecified != null) {
			this.specificCombo.select(this.specificCombo.indexOf(this.currentSpecified.getName()));
		}
		else {
			this.specificCombo.deselectAll();
		}
		
		final String oldEncoded= this.currentEncoded;
		this.currentEncoded= REnvUtils.encode(this.currentREnv);
		if (!((this.currentEncoded != null) ? this.currentEncoded.equals(oldEncoded) : (null == oldEncoded))) {
			for (final ChangeListener listener : this.listeners.toList()) {
				listener.settingChanged(this, oldEncoded, this.currentEncoded, this.currentREnv);
			}
		}
		else if (force) {
			checkBindings();
			if (this.bindings != null) {
				this.bindings.validateTargetToModel();
			}
		}
	}
	
	private void checkBindings() {
		if (this.bindindContext != null) {
			final IObservableList bindings= this.bindindContext.getBindings();
			for (final Object obj : bindings) {
				final Binding binding= (Binding) obj;
				if (binding.getTarget() instanceof CompositeObservable) {
					if (((CompositeObservable) binding.getTarget()).getComposite() == this) {
						this.bindings= binding;
						this.bindindContext= null;
						return;
					}
				}
			}
		}
	}
	
	
	public void addChangeListener(final ChangeListener listener) {
		this.listeners.add(listener);
	}
	
	public void removeChangeListener(final ChangeListener listener) {
		this.listeners.remove(listener);
	}
		
	/**
	 * Return a new Observable for the encoded setting of selected REnv.
	 * (So type is String)
	 */
	public IObservableValue createObservable(final Realm realm) {
		return new CompositeObservable(realm);
	}
	
	public ChooseREnvValidator createValidator(final DataBindingContext context) {
		this.bindindContext= context;
		return new ChooseREnvValidator();
	}
	
}
