/*=============================================================================#
 # 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.core.renv;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.ecommons.preferences.core.Preference;
import org.eclipse.statet.ecommons.preferences.core.Preference.IntPref;
import org.eclipse.statet.ecommons.preferences.core.Preference.LongPref;
import org.eclipse.statet.ecommons.preferences.core.Preference.StringPref;
import org.eclipse.statet.ecommons.preferences.core.PreferenceAccess;
import org.eclipse.statet.ecommons.preferences.core.PreferenceSetService;
import org.eclipse.statet.ecommons.preferences.core.util.PreferenceUtils;

import org.eclipse.statet.internal.r.core.Messages;
import org.eclipse.statet.internal.r.core.RCorePlugin;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.core.renv.IREnvConfiguration;
import org.eclipse.statet.r.core.renv.IREnvConfiguration.WorkingCopy;
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.rsetups.RSetup;
import org.eclipse.statet.rj.rsetups.RSetupUtil;


/**
 * Implementation of IREnvManager
 */
public class REnvManagerImpl implements IREnvManager {
	
	
	private static final String USER_ENV_PREFIX= "user-"; //$NON-NLS-1$
	private static final String USER_LOCAL_ID_PREFIX= IREnvConfiguration.USER_LOCAL_TYPE + '-';
	private static final String USER_REMOTE_ID_PREFIX= IREnvConfiguration.USER_REMOTE_TYPE + '-';
	private static final String CONTRIB_TEMP_REMOTE_ENV_ID_PREFIX= IREnvConfiguration.CONTRIB_TEMP_REMOTE_TYPE + '-';
	
	
	private static final StringPref PREF_DEFAULT_CONFIGURATION_NAME= new StringPref(
			IREnvManager.PREF_QUALIFIER, "default_configuration.name"); //$NON-NLS-1$
	
	private static final IntPref PREF_VERSION= new IntPref(
			IREnvManager.PREF_QUALIFIER, "version"); //$NON-NLS-1$
	
	private static final LongPref STAMP_PREF= new LongPref(
			IREnvManager.PREF_QUALIFIER, "stamp"); //$NON-NLS-1$
	
	private static @Nullable REnv getActualREnv(final REnv rEnv) {
		final IREnvConfiguration config= rEnv.get(IREnvConfiguration.class);
		return (config != null) ? config.getREnv() : null;
	}
	
	
	private volatile int state;
	private final ReadWriteLock lock;
	
	private Map<String, REnvConfigurationImpl> idMap;
	private final AliasREnv defaultEnv= new AliasREnv(RCore.DEFAULT_WORKBENCH_ENV_ID);
	
	
	public REnvManagerImpl() {
		this.state= 0;
		this.lock= new ReentrantReadWriteLock(true);
	}
	
	@Override
	public Lock getReadLock() {
		return this.lock.readLock();
	}
	
	public void dispose() {
		this.lock.writeLock().lock();
		try {
			this.state= 2;
			if (this.idMap != null) {
				this.idMap.clear();
				this.idMap= null;
			}
		}
		finally {
			this.lock.writeLock().unlock();
		}
	}
	
	private void checkAndLock(final boolean writeLock) {
		// check, if lazy loading is required
		if (this.state < 1) {
			synchronized (this) {
				try {
					if (this.state < 1) {
						load();
						this.state= 1;
					}
				}
				catch (final BackingStoreException e) {
					this.state= 101;
					RCorePlugin.logError(Messages.REnvManager_error_Accessing_message, e);
				}
			}
		}
		
		// lock and check ready
		if (writeLock) {
			this.lock.writeLock().lock();
		}
		else {
			this.lock.readLock().lock();
		}
		if (this.state > 1) {
			throw new IllegalStateException(Messages.REnvManager_error_Dispose_message);
		}
	}
	
	private boolean update(final ImList<IREnvConfiguration> configs, final String defaultREnvId) {
		final Set<String> newREnvs= new HashSet<>();
		for (final IREnvConfiguration config : configs) {
			newREnvs.add(config.getREnv().getId());
		}
		final Set<String> oldIds= new HashSet<>(this.idMap.keySet());
		
		// update or add configurations
		boolean changed= false;
		for (final IREnvConfiguration config : configs) {
			changed= doAdd(config, changed);
			final REnv rEnv= config.getREnv();
			oldIds.remove(rEnv.getId());
		}
		// remove old configurations
		for (final String id : oldIds) {
			changed= doDelete(id, changed);
		}
		
		changed= doSetDefault(defaultREnvId, changed);
		
		// dirty?
		return changed;
	}
	
	private boolean doAdd(final IREnvConfiguration config, boolean changed) {
		final REnvConfigurationImpl newConfig= new REnvConfigurationImpl(config);
		final ActualREnv rEnv= (ActualREnv) newConfig.getREnv();
		final IREnvConfiguration oldConfig= this.idMap.put(rEnv.getId(), newConfig);
		
		rEnv.name= newConfig.getName();
		rEnv.config= newConfig;
		
		if (!changed && !Objects.equals(oldConfig, newConfig)) {
			changed= true;
		}
		return changed;
	}
	
	private boolean doDelete(final String id, boolean changed) {
		final REnvConfigurationImpl rEnvConfig= this.idMap.remove(id);
		if (rEnvConfig != null) {
			final ActualREnv rEnv= (ActualREnv) rEnvConfig.getREnv();
			rEnv.isDeleted= true;
//			rEnv.config= null;
			changed |= true;
		}
		
		return changed;
	}
	
	private boolean doSetDefault(final String id, boolean changed) {
		final REnv oldDefault= getActualREnv(this.defaultEnv);
		updateDefault(id);
		final REnv newDefault= getActualREnv(this.defaultEnv);
		
		if (!changed && !Objects.equals(oldDefault, newDefault)) {
			changed= true;
		}
		return changed;
	}
	
	private boolean doRefreshDefault(boolean changed) {
		final REnv oldDefault= getActualREnv(this.defaultEnv);
		updateDefault((oldDefault != null) ? oldDefault.getId() : null);
		final REnv newDefault= getActualREnv(this.defaultEnv);
		
		if (!changed && !Objects.equals(oldDefault, newDefault)) {
			changed= true;
		}
		return changed;
	}
	
	
	private void updateDefault(final String defaultConfigId) {
		IREnvConfiguration rEnvConfig= null;
		if (defaultConfigId != null && !defaultConfigId.isEmpty()) {
			rEnvConfig= this.idMap.get(defaultConfigId);
		}
		String name;
		REnv rEnv;
		if (rEnvConfig != null) {
			name= rEnvConfig.getName();
			rEnv= rEnvConfig.getREnv();
		}
		else if (this.idMap.size() > 0) {
			name= Messages.REnvManager_status_NoDefault_label;
			rEnv= null;
		}
		else {
			name= Messages.REnvManager_status_NotAny_label;
			rEnv= null;
		}
		this.defaultEnv.name= name;
		this.defaultEnv.link= rEnv;
	}
	
	private void load() throws BackingStoreException {
		this.idMap= new HashMap<>();
		
		loadFromRegistry();
		loadFromWorkspace();
	}
	
	private void loadFromWorkspace() throws BackingStoreException {
		final PreferenceAccess prefs= PreferenceUtils.getInstancePrefs();
		final List<IREnvConfiguration>configs= new ArrayList<>();
		
		final Integer version= prefs.getPreferenceValue(PREF_VERSION);
		if (version == null || version.intValue() == 0) {
			for (final Iterator<IScopeContext> iter= prefs.getPreferenceContexts().iterator();
					configs.isEmpty() && iter.hasNext(); ) {
				final IEclipsePreferences prefNode= iter.next().getNode(IREnvManager.PREF_QUALIFIER);
				if (prefNode == null) {
					continue;
				}
				final String[] names= prefNode.childrenNames();
				for (final String name : names) {
					final Preferences node= prefNode.node(name);
					final String id= node.get("id", null); //$NON-NLS-1$
					if (id != null && id.length() > 0 && id.startsWith(USER_ENV_PREFIX)) {
						final ActualREnv rEnv= new ActualREnv(id);
						final REnvConfigurationImpl config= new REnvConfigurationImpl(
								null, rEnv, prefs, name);
						if (config.getName() != null) {
							config.upgradePref();
							rEnv.name= config.getName();
							rEnv.config= config;
							this.idMap.put(id, config);
						}
					}
				}
			}
		}
		else if (version.intValue() == 2) {
			for (final Iterator<IScopeContext> iter= prefs.getPreferenceContexts().iterator();
					configs.isEmpty() && iter.hasNext(); ) {
				final IEclipsePreferences prefNode= iter.next().getNode(IREnvManager.PREF_QUALIFIER);
				if (prefNode == null) {
					continue;
				}
				final String[] names= prefNode.childrenNames();
				for (final String id : names) {
					if (id != null && id.length() > 0 && id.startsWith(USER_ENV_PREFIX)) {
						final ActualREnv rEnv= new ActualREnv(id);
						final REnvConfigurationImpl config= new REnvConfigurationImpl(
								null, rEnv, prefs, null);
						if (config.getName() != null) {
							rEnv.name= config.getName();
							rEnv.config= config;
							this.idMap.put(id, config);
						}
					}
				}
			}
		}
		
		// init default config
		updateDefault(prefs.getPreferenceValue(PREF_DEFAULT_CONFIGURATION_NAME));
	}
	
	private void saveToWorkspace(final boolean envPrefs) throws BackingStoreException {
		final IScopeContext context= PreferenceUtils.getInstancePrefs().getPreferenceContexts().get(0);
		final IEclipsePreferences node= context.getNode(IREnvManager.PREF_QUALIFIER);
		
		final Map<Preference<?>, Object> map= new HashMap<>();
		map.put(PREF_VERSION, 2);
		map.put(STAMP_PREF, System.currentTimeMillis());
		
		if (envPrefs) {
			final List<String> oldNames= new ArrayList<>(Arrays.asList(node.childrenNames()));
			oldNames.removeAll(this.idMap.keySet());
			for (final String name : oldNames) {
				if (node.nodeExists(name)) {
					node.node(name).removeNode();
				}
			}
			
			for (final IREnvConfiguration config : this.idMap.values()) {
				if (config instanceof REnvConfigurationImpl
						&& !config.getType().startsWith("contrib.temp-") ) {
					((REnvConfigurationImpl) config).deliverToPreferencesMap(map);
				}
			}
		}
		{	// default
			final REnv rEnv= getActualREnv(this.defaultEnv);
			map.put(PREF_DEFAULT_CONFIGURATION_NAME, (rEnv != null) ? rEnv.getId() : null);
		}
		
		PreferenceUtils.setPrefValues(InstanceScope.INSTANCE, map);
		node.flush();
	}
	
	private void loadFromRegistry() {
		final PreferenceAccess prefs= PreferenceUtils.getInstancePrefs();
		final List<RSetup> setups= RSetupUtil.loadAvailableSetups(null);
		for (final RSetup setup : setups) {
			final ActualREnv rEnv= new ActualREnv(IREnvConfiguration.EPLUGIN_LOCAL_TYPE + '-' + setup.getId());
			final REnvConfigurationImpl config= new REnvConfigurationImpl(
					IREnvConfiguration.EPLUGIN_LOCAL_TYPE, rEnv, setup, prefs );
			
			rEnv.name= config.getName();
			rEnv.config= config;
			
			this.idMap.put(rEnv.getId(), config);
		}
	}
	
	private void onChanged(final boolean envPrefs) throws BackingStoreException {
		final PreferenceSetService preferenceSetService= PreferenceUtils.getPreferenceSetService();
		final String sourceId= "REnv" + System.identityHashCode(this); //$NON-NLS-1$
		final boolean resume= preferenceSetService.pause(sourceId);
		try {
			saveToWorkspace(envPrefs);
			return;
		}
		finally {
			if (resume) {
				preferenceSetService.resume(sourceId);
			}
		}
	}
	
	
	@Override
	public void set(final ImList<IREnvConfiguration> configs, final String defaultConfigId)
			throws CoreException {
		checkAndLock(true);
		try {
			final boolean changed= update(configs, defaultConfigId);
			if (!changed) {
				return;
			}
			
			onChanged(true);
		}
		catch (final BackingStoreException e) {
			throw new CoreException(new Status(IStatus.ERROR, RCore.BUNDLE_ID, -1, Messages.REnvManager_error_Saving_message, e));
		}
		finally {
			this.lock.writeLock().unlock();
		}
	}
	
	@Override
	public void add(final @NonNull REnvConfiguration rEnvConfig) {
		final REnv rEnv= rEnvConfig.getREnv();
		if (!rEnv.getId().startsWith(CONTRIB_TEMP_REMOTE_ENV_ID_PREFIX)) {
			throw new IllegalArgumentException();
		}
		
		checkAndLock(true);
		try {
			boolean changed= false;
			changed= doAdd((IREnvConfiguration) rEnvConfig, changed);
			if (!changed) {
				return;
			}
			
			changed= doRefreshDefault(changed);
			
			onChanged(false);
		}
		catch (final BackingStoreException e) {
			RCorePlugin.logError(Messages.REnvManager_error_Saving_message, e);
		}
		finally {
			this.lock.writeLock().unlock();
		}
	}
	
	@Override
	public void delete(final @NonNull REnv rEnv) {
		if (!rEnv.getId().startsWith(CONTRIB_TEMP_REMOTE_ENV_ID_PREFIX)) {
			throw new IllegalArgumentException();
		}
		
		checkAndLock(true);
		try {
			boolean changed= false;
			changed= doDelete(rEnv.getId(), changed);
			if (!changed) {
				return;
			}
			
			changed= doRefreshDefault(changed);
			
			onChanged(false);
		}
		catch (final BackingStoreException e) {
			RCorePlugin.logError(Messages.REnvManager_error_Saving_message, e);
		}
		finally {
			this.lock.writeLock().unlock();
		}
	}
	
//	public String[] getNames() {
//		checkAndLock(false);
//		try {
//			return this.names.toArray(new String[this.names.size()]);
//		}
//		finally {
//			this.lock.readLock().unlock();
//		}
//	}
	
	@Override
	public ImList<REnv> list() {
		final List<IREnvConfiguration> configList;
		checkAndLock(false);
		try {
			configList= new ArrayList<>(this.idMap.values());
		}
		finally {
			this.lock.readLock().unlock();
		}
		final REnv[] list= new REnv[configList.size()];
		int i= 0;
		for (final IREnvConfiguration config : configList) {
			final REnv rEnv= config.getREnv();
			if (!rEnv.isDeleted()) {
				list[i++]= rEnv;
			}
		}
		return ImCollections.newList(list, 0, i);
	}
	
	@Override
	public List<IREnvConfiguration> getConfigurations() {
		final List<IREnvConfiguration> list;
		checkAndLock(false);
		try {
			list= new ArrayList<>(this.idMap.values());
		}
		finally {
			this.lock.readLock().unlock();
		}
		final Iterator<IREnvConfiguration> iter= list.iterator();
		while (iter.hasNext()) {
			if (iter.next().getREnv().isDeleted()) {
				iter.remove();
			}
		}
		return list;
	}
	
	public String[] getIds() {
		checkAndLock(false);
		try {
			final Collection<String> keys= this.idMap.keySet();
			return keys.toArray(new String[keys.size()]);
		}
		finally {
			this.lock.readLock().unlock();
		}
	}
	
	@Override
	public synchronized @Nullable REnv get(final String id, final String name) {
		checkAndLock(false);
		try {
			if (id != null) {
				final REnv rEnv= getEnv(id);
				if (rEnv != null) {
					return rEnv;
				}
			}
			if (name != null) {
				return getEnvByName(name);
			}
			return null;
		}
		finally {
			this.lock.readLock().unlock();
		}
	}
	
	private @Nullable REnv getEnv(final String id) {
		if (id.equals(RCore.DEFAULT_WORKBENCH_ENV_ID)) {
			return this.defaultEnv;
		}
		IREnvConfiguration config= this.idMap.get(id);
		if (config == null) {
			config= this.idMap.get(id);
		}
		if (config != null) {
			return config.getREnv();
		}
		return null;
	}
	
	private @Nullable REnv getEnvByName(final String name) {
		for (final REnvConfiguration config : this.idMap.values()) {
			if (config.getName().equals(name)) {
				return config.getREnv();
			}
		}
		return null;
	}
	
	@Override
	public REnv getDefault() {
		checkAndLock(false);
		try {
			return this.defaultEnv;
		}
		finally {
			this.lock.readLock().unlock();
		}
	}
	
	@Override
	public WorkingCopy newConfiguration(final String type) {
		return new REnvConfigurationImpl.Editable(type, newLink(type));
	}
	
	private ActualREnv newLink(final String type) {
		return new ActualREnv(type + '-' + Long.toString(
				((long) System.getProperty("user.name").hashCode() << 32) | System.currentTimeMillis(), //$NON-NLS-1$
				36 ));
	}
	
}
