/*=============================================================================#
 # Copyright (c) 2007, 2020 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<Object> {
		
		@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 IValidator<Object> createValidator(final DataBindingContext context) {
		this.bindindContext= context;
		return new ChooseREnvValidator();
	}
	
}
