/*=============================================================================#
 # Copyright (c) 2010, 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.core.rhelp;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.core.runtime.jobs.Job;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImIdentitySet;
import org.eclipse.statet.jcommons.lang.Disposable;

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

import org.eclipse.statet.internal.r.core.RCorePlugin;
import org.eclipse.statet.internal.r.core.renv.REnvConfiguration;
import org.eclipse.statet.internal.r.core.renv.REnvManager;
import org.eclipse.statet.internal.r.core.rhelp.RHelpWebapp.ContentInfo;
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.rhelp.IRHelpManager;
import org.eclipse.statet.r.core.rhelp.IRHelpPage;
import org.eclipse.statet.r.core.rhelp.IRHelpSearchRequestor;
import org.eclipse.statet.r.core.rhelp.IRPkgHelp;
import org.eclipse.statet.r.core.rhelp.RHelpSearchQuery;


public class RHelpManager implements IRHelpManager, PreferenceSetService.ChangeListener, Disposable {
// Compatible to dynamic R help
// 1) With dynamic= TRUE from tools:::httpd()
//    Here generated links are of the forms
//    ../../pkg/help/topic
//    file.html
//    ../../pkg/html/file.html
//    and links are never missing: topics are always linked as
//    ../../pkg/help/topic for the current packages, and this means
//    'search this package then all the others, and show all matches
//    if we need to go outside this packages'
	
	
	private static final ImIdentitySet<String> PREF_QUALIFIERS= ImCollections.newIdentitySet(
			IREnvManager.PREF_QUALIFIER );
	
	
	private static class EnvItem {
		
		final String id;
		
		int state;
		
		REnvHelp help;
		String indexDir;
		
		final Object helpLock= new Object();
		final Object indexLock= new Object();
		
		public EnvItem(final String id) {
			this.id= id;
			this.state= 0;
			this.help= null;
			this.indexDir= null;
		}
		
	}
	
	private class InitJob extends Job {
		
		public InitJob() {
			super("Prepare R help");
			setSystem(true);
			setPriority(Job.DECORATE);
		}
		
		@Override
		protected IStatus run(final IProgressMonitor monitor) {
			ensureIsRunning();
			
			final IREnv rEnv= RHelpManager.this.rEnvManager.getDefault().resolve();
			if (rEnv != null) {
				final REnvHelp help= getHelp(rEnv);
				if (help != null) {
					help.unlock();
				}
			}
			
			return Status.OK_STATUS;
		}
		
	}
	
	private static final int HELP_LOADED= 1;
	private static final int HELP_MISSING= -1;
	private static final int RENV_DELETED= -2;
	
	/**
	 * Searches topic in library
	 */
	private static final String RHELP_TOPIC_PATH= "/topic"; //$NON-NLS-1$
	
	/**
	 * Shows page (package, package/name or package/topic)
	 */
	private static final String RHELP_PAGE_PATH= "/page"; //$NON-NLS-1$
	
	
	private final PreferenceAccess prefAccess;
	
	private final REnvManager rEnvManager= RCorePlugin.getInstance().getREnvManager();
	private boolean running;
	
	private boolean httpdStarted;
	private JettyServer httpd;
	
	private final Object indexLock= new Object();
	
	private final SaveUtil saveUtil= new SaveUtil();
	
	private final Map<String, EnvItem> helpIndexes= new HashMap<>();
	
	
	public RHelpManager() {
		this.prefAccess= PreferenceUtils.getInstancePrefs();
		this.prefAccess.addPreferenceSetListener(this, PREF_QUALIFIERS);
		new InitJob().schedule(1000);
	}
	
	
	@Override
	public String getPageHttpUrl(final IRHelpPage page, final String target) {
		final IRPkgHelp pkgHelp= page.getPackage();
		return getPageHttpUrl(pkgHelp.getName(), page.getName(), pkgHelp.getREnv(), target);
	}
	
	@Override
	public String getPageHttpUrl(final String packageName, final String pageName,
			final IREnv rEnv, final String target) {
		checkRunning();
		final StringBuilder sb= new StringBuilder(64);
		sb.append(RHelpWebapp.CONTEXT_PATH);
		sb.append('/');
		sb.append(target);
		sb.append('/');
		sb.append(rEnv.getId());
		sb.append('/');
		sb.append(RHelpWebapp.CAT_LIBRARY);
		sb.append('/');
		sb.append(packageName);
		sb.append('/');
		if (pageName != null) {
			sb.append(RHelpWebapp.COMMAND_HTML_PAGE);
			sb.append('/');
			sb.append(pageName);
			sb.append(".html"); //$NON-NLS-1$
		}
		return createUrl(sb.toString());
	}
	
	@Override
	public String getTopicHttpUrl(final String topic, final String packageName,
			final IREnv rEnv, final String target) {
		checkRunning();
		final StringBuilder sb= new StringBuilder(64);
		sb.append(RHelpWebapp.CONTEXT_PATH);
		sb.append('/');
		sb.append(target);
		sb.append('/');
		sb.append(rEnv.getId());
		sb.append('/');
		sb.append(RHelpWebapp.CAT_LIBRARY);
		sb.append('/');
		sb.append(packageName);
		sb.append('/');
		sb.append(RHelpWebapp.COMMAND_HELP_TOPIC);
		sb.append('/');
		sb.append(topic);
		return createUrl(sb.toString());
	}
	
	@Override
	public String getREnvHttpUrl(final IREnv rEnv, final String target) {
		checkRunning();
		final StringBuilder sb= new StringBuilder(64);
		sb.append(RHelpWebapp.CONTEXT_PATH);
		sb.append('/');
		sb.append(target);
		sb.append('/');
		sb.append(rEnv.getId());
		sb.append('/');
		return createUrl(sb.toString());
	}
	
	@Override
	public String getPackageHttpUrl(final IRPkgHelp pkgHelp, final String target) {
		return getPageHttpUrl(pkgHelp.getName(), null, pkgHelp.getREnv(), target);
	}
	
	@Override
	public String toHttpUrl(final String url, final IREnv rEnv, final String target) {
		checkRunning();
		if (url.startsWith("rhelp:///")) { //$NON-NLS-1$
			final StringBuilder sb= new StringBuilder(64);
			sb.append(RHelpWebapp.CONTEXT_PATH);
			sb.append('/');
			sb.append(target);
			
			final String path= url.substring(8);
			final int idx1= (path.length() > 0) ? path.indexOf('/', 1) : -1;
			if (idx1 > 0) {
				final String command= path.substring(0, idx1);
				if (command.equals(RHELP_PAGE_PATH)) {
					sb.append('/');
					sb.append(rEnv.getId());
					sb.append('/');
					sb.append(RHelpWebapp.CAT_LIBRARY);
					final int idx2= path.indexOf('/', idx1 + 1);
					if (idx2 > idx1 + 1 && idx2 < path.length() - 1) {
						sb.append('/');
						sb.append(path.substring(idx1 + 1, idx2));
						sb.append('/');
						sb.append(RHelpWebapp.COMMAND_HTML_PAGE);
						sb.append('/');
						sb.append(path.substring(idx2 + 1));
						sb.append(".html"); //$NON-NLS-1$
					}
					else {
						sb.append('/');
						sb.append(path.substring(idx1 + 1, (idx2 > 0) ? idx2 : path.length()));
						sb.append('/');
					}
					return createUrl(sb.toString());
				}
				else if (command.equals(RHELP_TOPIC_PATH)) {
					sb.append('/');
					sb.append(rEnv.getId());
					sb.append('/');
					sb.append(RHelpWebapp.CAT_LIBRARY);
					sb.append('/');
					sb.append('-');
					sb.append('/');
					sb.append(RHelpWebapp.COMMAND_HELP_TOPIC);
					sb.append('/');
					sb.append(path.substring(idx1 + 1));
					return createUrl(sb.toString());
				}
			}
			else if (path.length() == 1) { // start
				sb.append('/');
				sb.append(rEnv.getId());
				sb.append('/');
				return createUrl(sb.toString());
			}
			return null;
		}
		if (url.startsWith("http://") && (rEnv != null || target != null)) { //$NON-NLS-1$
			try {
				final URI uri= new URI(url);
				if (isDynamic(uri)) {
					final String path= uri.getPath();
					if (path != null && path.startsWith(RHelpWebapp.CONTEXT_PATH)) {
						final int idx2= path.indexOf('/', RHelpWebapp.CONTEXT_PATH.length() + 1);
						if (idx2 >= 0) {
							final StringBuilder sb= new StringBuilder(path.length() + 16);
							sb.append(RHelpWebapp.CONTEXT_PATH);
							sb.append('/');
							sb.append((target != null) ? target :
									path.substring(RHelpWebapp.CONTEXT_PATH.length() + 1, idx2));
							final String info= path.substring(idx2 + 1);
							if (rEnv != null) {
								final int idx3= info.indexOf('/');
								if (idx3 < 0) {
									return null;
								}
								sb.append('/');
								sb.append(rEnv.getId());
								sb.append(info.substring(idx3));
							}
							else {
								sb.append('/');
								sb.append(info);
							}
							return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(),
									sb.toString(), uri.getQuery(), uri.getFragment()).toString();
						}
					}
					return null;
				}
			}
			catch (final Exception e) {}
		}
		return url;
	}
	
	@Override
	public String toHttpUrl(final Object object, final String target) {
		if (object == this) {
			return "about:blank"; //$NON-NLS-1$
		}
		if (object instanceof IREnv) {
			return getREnvHttpUrl((IREnv) object, target);
		}
		if (object instanceof IREnvConfiguration) {
			return getREnvHttpUrl(((IREnvConfiguration) object).getReference(), target);
		}
		if (object instanceof IRPkgHelp) {
			return getPackageHttpUrl((IRPkgHelp) object, target);
		}
		if (object instanceof IRHelpPage) {
			return getPageHttpUrl((IRHelpPage) object, target);
		}
		if (object instanceof String) {
			final String s= (String) object;
			if (s.startsWith("http://")) { //$NON-NLS-1$
				return s;
			}
		}
		return null;
	}
	
	private String createUrl(final String path) {
		try {
			return new URI("http", null, this.httpd.getHost(), this.httpd.getPort(), path, null, null) //$NON-NLS-1$
					.toASCIIString();
		}
		catch (final URISyntaxException e) {
			throw new IllegalStateException(e);
		}
	}
	
	@Override
	public Object getContentOfUrl(final String url) {
		try {
			final URI uri= new URI(url);
			final String path= uri.getPath();
			if (uri.getScheme() != null && uri.getScheme().equals("http") //$NON-NLS-1$
					&& path != null && path.startsWith(RHelpWebapp.CONTEXT_PATH)) {
				final int idx2= path.indexOf('/', RHelpWebapp.CONTEXT_PATH.length() + 1);
				if (idx2 >= 0) {
					final ContentInfo info= RHelpWebapp.extractContent(path.substring(idx2));
					if (info != null) {
						final IREnv rEnv= this.rEnvManager.get(info.rEnvId, null);
						if (rEnv != null && info.cat == RHelpWebapp.CAT_LIBRARY) {
							final REnvHelp help= getHelp(rEnv);
							if (help != null) {
								try {
									final IRPkgHelp pkgHelp= help.getPkgHelp(info.packageName);
									if (pkgHelp != null && info.command == RHelpWebapp.COMMAND_HTML_PAGE) {
										final IRHelpPage page= pkgHelp.getHelpPage(info.detail);
										if (page != null) {
											return page;
										}
									}
									return pkgHelp;
								}
								finally {
									help.unlock();
								}
							}
							return null;
						}
						if (rEnv != null && info.cat == RHelpWebapp.CAT_DOC) {
							return new Object[] { rEnv, null };
						}
						return rEnv;
					}
				}
			}
		} catch (final URISyntaxException e) {}
		return null;
	}
	
	@Override
	public boolean ensureIsRunning() {
		if (!this.httpdStarted) {
			startServer();
		}
		return this.running;
	}
	
	@Override
	public boolean isDynamic(final URI url) {
		checkRunning();
		return ((this.httpd.getHost().equals(url.getHost()) && this.httpd.getPort() == url.getPort()
				|| PORTABLE_URL_SCHEME.equals(url.getScheme()) ));
	}
	
	@Override
	public URI toHttpUrl(final URI url) throws URISyntaxException {
		if (isDynamic(url)) {
			String path= url.getPath();
			if (path != null && !path.startsWith("/rhelp")) {
				path= "/rhelp" + path;
			}
			return new URI("http", null, this.httpd.getHost(), this.httpd.getPort(),
					path, url.getQuery(), url.getFragment());
		}
		return url;
	}
	
	@Override
	public URI toPortableUrl(final URI url) throws URISyntaxException {
		if (isDynamic(url)) {
			String path= url.getPath();
			if (path != null && path.startsWith("/rhelp")) {
				path= path.substring(6);
			}
			return new URI(PORTABLE_URL_SCHEME, null, null, -1,
					path, url.getQuery(), url.getFragment());
		}
		return url;
	}
	
	private void checkRunning() {
		if (!ensureIsRunning()) {
			throw new UnsupportedOperationException("Help is not available.");
		}
	}
	
	private synchronized void startServer() {
		if (this.httpdStarted) {
			return;
		}
		final JettyServer httpd= new JettyServer();
		try {
			httpd.startServer();
			this.httpd= httpd;
			this.running= true;
		}
		catch (final Exception e) {
			RCorePlugin.log(new Status(IStatus.ERROR, RCore.BUNDLE_ID, -1,
						"An error occured when starting webserver for R help.", e));
			try {
				httpd.stopServer();
			}
			catch (final Exception ignore) {}
		}
		this.httpdStarted= true;
	}
	
	private synchronized void stopServer() {
		if (this.httpd == null) {
			return;
		}
		this.running= false;
		try {
			this.httpd.stopServer();
			this.httpd= null;
		}
		catch (final Exception e) {
			RCorePlugin.log(new Status(IStatus.ERROR, RCore.BUNDLE_ID, -1,
					"An error occured when stopping webserver for R help.", e));
		}
	}
	
	
	@Override
	public void search(final RHelpSearchQuery query, final IRHelpSearchRequestor requestor,
			final IProgressMonitor monitor) throws CoreException {
		if (query == null) {
			throw new NullPointerException("query"); //$NON-NLS-1$
		}
		if (requestor == null) {
			throw new NullPointerException("requestor"); //$NON-NLS-1$
		}
		final RHelpSearchQuery.Compiled compiledQuery= query.compile();
		final REnvHelp help= getHelp(compiledQuery.getREnv());
		if (help != null) {
			try {
				if (!help.search(compiledQuery, requestor)) {
					throw new CoreException(new Status(IStatus.ERROR, RCore.BUNDLE_ID, -1,
							"An internal error occurend when performing R help search.", null));
				}
			}
			finally {
				help.unlock();
			}
		}
		else {
			final IREnv rEnv= query.getREnv();
			if (rEnv == null || rEnv.getConfig() == null) {
				throw new CoreException(new Status(IStatus.ERROR, RCore.BUNDLE_ID, -1,
						"The selected R environment doesn't exists.", null));
			}
			else {
				throw new CoreException(new Status(IStatus.ERROR, RCore.BUNDLE_ID, -1,
						"The R library of the selected R environment <code>" + compiledQuery.getREnv().getName() +
						"</code> is not yet indexed. Please run the indexer first to enable R help support.", null));
			}
		}
	}
	
	
	@Override
	public void preferenceChanged(final ChangeEvent event) {
		if (event.contains(IREnvManager.PREF_QUALIFIER)) {
			final List<IREnvConfiguration> configurations= this.rEnvManager.getConfigurations();
			final EnvItem[] items= new EnvItem[configurations.size()]; 
			synchronized (this.indexLock) {
				for (int i= 0; i < configurations.size(); i++) {
					items[i]= this.helpIndexes.get(configurations.get(i).getReference().getId());
				}
			}
			for (int i= 0; i < configurations.size(); i++) {
				if (items[i] != null) {
					final EnvItem item= items[i];
					final IREnvConfiguration config= configurations.get(i);
					REnvHelp oldHelp= null;
					synchronized (item.helpLock) {
						if (!((item.indexDir != null) ? 
								item.indexDir.equals(config.getIndexDirectoryPath()) :
								null == config.getIndexDirectoryPath() )) {
							item.state= 0;
							oldHelp= item.help;
							item.help= null;
						}
					}
					if (oldHelp != null) {
						oldHelp.dispose();
					}
				}
			}
		}
	}
	
	public boolean updateHelp(final IREnvConfiguration rEnvConfig, 
			final Map<String, String> rEnvSharedProperties, final REnvHelp help) {
		final IREnv rEnv= help.getREnv();
		final String rEnvId= rEnv.getId();
		EnvItem item;
		synchronized (this.indexLock) {
			item= this.helpIndexes.get(rEnvId);
			if (item == null) {
				item= new EnvItem(rEnvId);
				this.helpIndexes.put(rEnvId, item);
			}
		}
		REnvHelp oldHelp= null;
		try {
			synchronized (item.helpLock) {
				if (item.state == RENV_DELETED) {
					oldHelp= help;
					return false;
				}
				item.state= HELP_LOADED;
				item.indexDir= rEnvConfig.getIndexDirectoryPath();
				oldHelp= item.help;
				item.help= help;
				this.saveUtil.save(rEnvConfig, help);
				if (rEnvConfig instanceof REnvConfiguration) {
					((REnvConfiguration) rEnvConfig).updateSharedProperties(rEnvSharedProperties);
				}
				return true;
			}
		}
		finally {
			if (oldHelp != null) {
				oldHelp.dispose();
			}
		}
	}
	
	public void delete(final String id) {
		if (id != null && id.length() > 0) {
			EnvItem item;
			synchronized (this.indexLock) {
				item= this.helpIndexes.get(id);
				if (item == null) {
					item= new EnvItem(id);
					this.helpIndexes.put(id, item);
				}
			}
			REnvHelp oldHelp= null;
			synchronized (item.helpLock) {
				item.state= RENV_DELETED;
				oldHelp= item.help;
				item.help= null;
			}
			if (oldHelp != null) {
				oldHelp.dispose();
			}
		}
	}
	
	@Override
	public List<IREnv> getREnvWithHelp() {
		final List<IREnvConfiguration> configurations= this.rEnvManager.getConfigurations();
		final EnvItem[] items= new EnvItem[configurations.size()];
		synchronized (this.indexLock) {
			for (int i= 0; i < configurations.size(); i++) {
				final String id= configurations.get(i).getReference().getId();
				EnvItem item= this.helpIndexes.get(id);
				if (item == null) {
					item= new EnvItem(id);
					this.helpIndexes.put(id, item);
				}
				items[i]= item;
			}
		}
		final List<IREnv> withHelp= new ArrayList<>(configurations.size());
		for (int i= 0; i < items.length; i++) {
			final EnvItem item= items[i];
			final IREnvConfiguration rEnvConfig= configurations.get(i);
			if (rEnvConfig.isDeleted()) {
				continue;
			}
			synchronized (item.helpLock) {
				switch (item.state) {
				case HELP_LOADED:
					withHelp.add(rEnvConfig.getReference());
					continue;
				case 0:
					if (this.saveUtil.hasIndex(rEnvConfig)) {
						withHelp.add(rEnvConfig.getReference());
					}
					else {
						item.state= HELP_MISSING;
					}
					continue;
				default:
					continue;
				}
			}
		}
		return withHelp;
	}
	
	@Override
	public boolean hasHelp(IREnv rEnv) {
		if (rEnv != null) {
			rEnv= rEnv.resolve();
			
			if (rEnv != null) {
				final String id= rEnv.getId();
				EnvItem item;
				synchronized (this.indexLock) {
					item= this.helpIndexes.get(id);
					if (item == null) {
						item= new EnvItem(id);
						this.helpIndexes.put(id, item);
					}
				}
				synchronized (item.helpLock) {
					switch (item.state) {
					case HELP_LOADED:
						return true;
					case 0:
						if (this.saveUtil.hasIndex(rEnv.getConfig())) {
							return true;
						}
						else {
							item.state= HELP_MISSING;
							return false;
						}
					default:
						return false;
					}
				}
			}
		}
		return false;
	}
	
	@Override
	public REnvHelp getHelp(IREnv rEnv) {
		if (rEnv != null) {
			rEnv= rEnv.resolve();
			
			if (rEnv != null) {
				final String rEnvId= rEnv.getId();
				EnvItem item;
				synchronized (this.indexLock) {
					item= this.helpIndexes.get(rEnvId);
					if (item == null) {
						item= new EnvItem(rEnvId);
						this.helpIndexes.put(rEnvId, item);
					}
				}
				synchronized (item.helpLock) {
					switch (item.state) {
					case HELP_LOADED:
						item.help.lock();
						return item.help;
					case 0:
						final IREnvConfiguration rEnvConfig= rEnv.getConfig();
						if (rEnvConfig != null) {
							item.indexDir= rEnvConfig.getIndexDirectoryPath();
							item.help= this.saveUtil.load(rEnvConfig);
						}
						if (item.help != null) {
							item.state= HELP_LOADED;
							item.help.lock();
							return item.help;
						}
						else {
							item.state= HELP_MISSING;
							return null;
						}
					default:
						return null;
					}
				}
			}
		}
		return null;
	}
	
	public Object getIndexLock(final IREnv rEnv) {
		final String id= rEnv.getId();
		EnvItem item;
		synchronized (this.indexLock) {
			item= this.helpIndexes.get(id);
			if (item == null) {
				item= new EnvItem(id);
				this.helpIndexes.put(id, item);
			}
		}
		return item.indexLock;
	}
	
	@Override
	public void dispose() {
		this.prefAccess.removePreferenceSetListener(this);
		
		stopServer();
	}
	
}
