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

import org.eclipse.statet.internal.r.debug.ui.preferences.REnvPreferencePage;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.core.renv.IREnvManager;
import org.eclipse.statet.rj.renv.core.REnv;
import org.eclipse.statet.rj.renv.core.REnvConfiguration;
import org.eclipse.statet.rj.renv.core.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<REnv> RENV_COMPARATOR= new Comparator<REnv>() {
		@Override
		public int compare(final REnv o1, final REnv o2) {
			return Collator.getInstance().compare(o1.getName(), o2.getName());
		}
	};
	
	
	public static interface ChangeListener {
		public void settingChanged(REnvSelectionComposite source, String oldValue, String newValue,
				REnv newREnv);
	}
	
	private class CompositeObservable extends AbstractObservableValue<String> implements ChangeListener {
		
		public CompositeObservable(final Realm realm) {
			super(realm);
			REnvSelectionComposite.this.addChangeListener(CompositeObservable.this);
		}
		
		@Override
		public Object getValueType() {
			return String.class;
		}
		
		@Override
		protected void doSetValue(final String value) {
			setEncodedSetting(value);
		}
		
		@Override
		protected String doGetValue() {
			return getEncodedSetting();
		}
		
		@Override
		public void settingChanged(final REnvSelectionComposite source, final String oldValue,
				final String newValue, final REnv newREnv) {
			fireValueChange(Diffs.createValueDiff(oldValue, newValue));
		}
		
		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 REnv rEnv= REnvSelectionComposite.this.currentREnv.resolve();
			if (rEnv == null
					|| (REnvSelectionComposite.this.validREnvs != null && !REnvSelectionComposite.this.validREnvs.contains(rEnv))
					|| rEnv.get(REnvConfiguration.class) == 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<REnv> validREnvs;
	
	private REnv currentREnv;
	private String currentEncoded;
	private REnv 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(LayoutUtils.newCompositeGrid(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));
		LayoutUtils.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 REnv defaultEnv= manager.getDefault();
			final List<? extends REnvConfiguration> 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<REnv> getValidREnvs(final List<? extends REnvConfiguration> configurations) {
		final List<REnv> list= new ArrayList<>(configurations.size());
		for (final REnvConfiguration rEnvConfig : configurations) {
			if (isValid(rEnvConfig)) {
				list.add(rEnvConfig.getREnv());
			}
		}
		return list;
	}
	
	protected boolean isValid(final REnvConfiguration rEnvConfig) {
		return (!rEnvConfig.getREnv().isDeleted());
	}
	
	public void setSetting(final REnv 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 REnv getSelection() {
		return this.currentREnv;
	}
	
	private void updateState(final boolean updateSelection, final boolean force) {
		final boolean isWorkbench= (this.currentREnv != null
				&& this.currentREnv.getId().equals(RCore.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<Binding> bindings= this.bindindContext.getBindings();
			for (final Binding binding : bindings) {
				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<String> createObservable(final Realm realm) {
		return new CompositeObservable(realm);
	}
	
	public ChooseREnvValidator createValidator(final DataBindingContext context) {
		this.bindindContext= context;
		return new ChooseREnvValidator();
	}
	
}
