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

import static org.eclipse.statet.internal.rhelp.core.RHelpWebapp.CAT_DOC;
import static org.eclipse.statet.internal.rhelp.core.RHelpWebapp.CAT_LIBRARY;
import static org.eclipse.statet.internal.rhelp.core.RHelpWebapp.LIBRARY_HELP;
import static org.eclipse.statet.internal.rhelp.core.RHelpWebapp.LIBRARY_HTML;
import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullElse;

import java.net.URI;
import java.net.URISyntaxException;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.internal.rhelp.core.RHelpWebapp;
import org.eclipse.statet.internal.rhelp.core.RHelpWebapp.RequestInfo;
import org.eclipse.statet.internal.rhelp.core.server.ServerClientSupport;
import org.eclipse.statet.rhelp.core.REnvHelp;
import org.eclipse.statet.rhelp.core.REnvHelpConfiguration;
import org.eclipse.statet.rhelp.core.RHelpManager;
import org.eclipse.statet.rhelp.core.RHelpPage;
import org.eclipse.statet.rhelp.core.RHelpTopicLookup;
import org.eclipse.statet.rhelp.core.RPkgHelp;
import org.eclipse.statet.rj.renv.core.REnv;
import org.eclipse.statet.rj.renv.core.REnvConfiguration;


@NonNullByDefault
public abstract class RHelpHttpService  {
	
	
	public static final String HTTP_SCHEME= "http"; //$NON-NLS-1$
	
	public static final String PORTABLE_URI_SCHEME= "erhelp"; //$NON-NLS-1$
	
	
	/**
	 * 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 static final String ABOUT_BLANK_URI_STRING= "about:blank"; //$NON-NLS-1$
	private static final URI ABOUT_BLANK_URI= URI.create(ABOUT_BLANK_URI_STRING);
	
	
	private final String contextPath= RHelpWebapp.CONTEXT_PATH;
	
	private final RHelpManager rHelpManager;

	public static final String BROWSE_TARGET= "browse"; //$NON-NLS-1$
	
	
	public RHelpHttpService(final RHelpManager rHelpManager) {
		this.rHelpManager= rHelpManager;
	}
	
	
	public abstract boolean ensureIsRunning();
	
	protected abstract String getHost();
	protected abstract int getPort();
	
	protected void checkRunning() {
		if (!ensureIsRunning()) {
			throw new UnsupportedOperationException("Help is not available.");
		}
	}
	
	
	public boolean isDynamicUrl(final URI url) {
		checkRunning();
		final String path;
		return (HTTP_SCHEME.equals(url.getScheme())
				&& getHost().equals(url.getHost()) && getPort() == url.getPort()
				&& (path= url.getPath()) != null && path.startsWith(this.contextPath) );
	}
	
	private String getDynamicPath(final URI url) {
		return url.getPath().substring(this.contextPath.length());
	}
	
	protected URI createHttpUrl(final StringBuilder encPath,
			final @Nullable String encQuery, final @Nullable String encFragment)
			throws URISyntaxException {
		final String host= getHost();
		final StringBuilder sb= new StringBuilder(host.length() + encPath.length() + 16);
		sb.append(HTTP_SCHEME);
		sb.append("://"); //$NON-NLS-1$
		sb.append(getHost());
		if (getPort() != -1) {
			sb.append(':');
			sb.append(getPort());
		}
		sb.append(encPath);
		if (encQuery != null) {
			sb.append('?');
			sb.append(encQuery);
		}
		if (encFragment != null) {
			sb.append('#');
			sb.append(encFragment);
		}
		return new URI(sb.toString());
	}
	
	protected URI createHttpUrl(final StringBuilder encPath) {
		try {
			return createHttpUrl(encPath, null, null);
		}
		catch (final URISyntaxException e) {
			throw new IllegalStateException(e);
		}
	}
	
	
	public URI getPageHttpUrl(final RHelpPage page, final String target) {
		final RPkgHelp pkgHelp= page.getPackage();
		return getPageHttpUrl(pkgHelp.getName(), page.getName(), pkgHelp.getREnv(), target);
	}
	
	public URI getPageHttpUrl(final String pkgName, final @Nullable String pageName,
			final REnv rEnv, final String target) {
		checkRunning();
		final StringBuilder p= new StringBuilder(64);
		p.append(this.contextPath);
		p.append('/');
		p.append(target);
		p.append('/');
		p.append(rEnv.getId());
		p.append('/');
		p.append(CAT_LIBRARY);
		p.append('/');
		p.append(pkgName);
		p.append('/');
		if (pageName != null) {
			p.append(LIBRARY_HTML);
			p.append('/');
			p.append(pageName);
			p.append(".html"); //$NON-NLS-1$
		}
		return createHttpUrl(p);
	}
	
	public URI getTopicHttpUrl(final String topic, final @Nullable String pkgName,
			final REnv rEnv, final String target) {
		checkRunning();
		final StringBuilder p= new StringBuilder(64);
		p.append(this.contextPath);
		p.append('/');
		p.append(target);
		p.append('/');
		p.append(rEnv.getId());
		p.append('/');
		p.append(CAT_LIBRARY);
		p.append('/');
		p.append((pkgName != null) ? pkgName : "-");
		p.append('/');
		p.append(LIBRARY_HELP);
		p.append('/');
		p.append(topic);
		return createHttpUrl(p);
	}
	
	public URI getREnvHttpUrl(final REnv rEnv, final String target) {
		checkRunning();
		final StringBuilder p= new StringBuilder(64);
		p.append(this.contextPath);
		p.append('/');
		p.append(target);
		p.append('/');
		p.append(rEnv.getId());
		p.append('/');
		return createHttpUrl(p);
	}
	
	public URI getPackageHttpUrl(final RPkgHelp pkgHelp, final String target) {
		return getPageHttpUrl(pkgHelp.getName(), null, pkgHelp.getREnv(), target);
	}
	
	public @Nullable URI toHttpUrl(final String url,
			final @Nullable REnv rEnv, final @Nullable String target) {
		checkRunning();
		if (url.startsWith("rhelp:///")) { //$NON-NLS-1$
			if (rEnv == null || target == null) {
				return null;
			}
			
			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)) {
					final int idx2= path.indexOf('/', idx1 + 1);
					if (idx2 > idx1 + 1 && idx2 < path.length() - 1) {
						return getPageHttpUrl(path.substring(idx1 + 1, idx2),
								path.substring(idx2 + 1), rEnv, target );
					}
					else {
						return getPageHttpUrl(path.substring(idx1 + 1, (idx2 > 0) ? idx2 : path.length()),
								null, rEnv, target );
					}
				}
				else if (command.equals(RHELP_TOPIC_PATH)) {
					return getTopicHttpUrl(path.substring(idx1 + 1), null, rEnv, target);
				}
			}
			else if (path.length() == 1) { // start
				return getREnvHttpUrl(rEnv, target);
			}
			return null;
		}
		if (url.startsWith("http://")) { //$NON-NLS-1$
			try {
				final URI uri= new URI(url);
				if (isDynamicUrl(uri)) {
					if (rEnv == null && target == null) {
						return null;
					}
					final String path= getDynamicPath(uri);
					final int targetEnd= path.indexOf('/', 1);
					if (targetEnd > 1) {
						final StringBuilder p= new StringBuilder(path.length() + 16);
						p.append(this.contextPath);
						p.append('/');
						p.append((target != null) ? target : path.substring(1, targetEnd));
						final String info= path.substring(targetEnd + 1);
						if (rEnv != null) {
							final int idx3= info.indexOf('/');
							if (idx3 < 0) {
								return null;
							}
							p.append('/');
							p.append(rEnv.getId());
							p.append(info.substring(idx3));
						}
						else {
							p.append('/');
							p.append(info);
						}
						return createHttpUrl(p, uri.getRawQuery(), uri.getRawFragment());
					}
					return null;
				}
				return uri;
			}
			catch (final Exception e) {}
		}
		return null;
	}
	
	
	public @Nullable URI toHttpUrl(final Object object, final String target) {
		if (object == this) {
			return ABOUT_BLANK_URI;
		}
		if (object instanceof REnv) {
			return getREnvHttpUrl((REnv) object, target);
		}
		if (object instanceof REnvHelpConfiguration) {
			return getREnvHttpUrl(((REnvHelpConfiguration) object).getREnv(), target);
		}
		if (object instanceof RPkgHelp) {
			return getPackageHttpUrl((RPkgHelp) object, target);
		}
		if (object instanceof RHelpPage) {
			return getPageHttpUrl((RHelpPage) object, target);
		}
		if (object instanceof RHelpTopicLookup) {
			final RHelpTopicLookup lookup= (RHelpTopicLookup) object;
			return getTopicHttpUrl(lookup.getTopic(), null, lookup.getREnv(), target);
		}
		if (object instanceof String) {
			final String s= (String) object;
			if (s.startsWith("http://")) { //$NON-NLS-1$
				try {
					return new URI(s);
				}
				catch (final URISyntaxException e) {}
			}
		}
		return null;
	}
	
	public @Nullable Object getContentOfUrl(final String url) {
		try {
			return getContentOfUrl(new URI(url));
		}
		catch (final URISyntaxException e) {
			return null;
		}
	}
	
	public @Nullable Object getContentOfUrl(final URI url) {
		if (isDynamicUrl(url)) {
			final String path= getDynamicPath(url);
			final int targetEnd= path.indexOf('/', 1);
			if (targetEnd > 1) {
				final RequestInfo info= RHelpWebapp.extractRequestInfo(path.substring(targetEnd));
				if (info != null) {
					final REnv rEnv= this.rHelpManager.getREnv(info.rEnvId);
					if (rEnv != null && info.cat == CAT_LIBRARY) {
						final REnvHelp help= this.rHelpManager.getHelp(rEnv);
						if (help != null) {
							try {
								final RPkgHelp pkgHelp= help.getPkgHelp(info.pkgName);
								if (pkgHelp != null && info.cmd == RHelpWebapp.PKGCMD_HTML_PAGE) {
									final RHelpPage page= pkgHelp.getPage(info.detail);
									if (page != null) {
										return page;
									}
								}
								return pkgHelp;
							}
							finally {
								help.unlock();
							}
						}
						return null;
					}
					if (rEnv != null && info.cat == CAT_DOC) {
						return new Object[] { rEnv, null };
					}
					return rEnv;
				}
			}
		}
		return null;
	}
	
	
	public boolean isPortableUrl(final URI url) {
		return PORTABLE_URI_SCHEME.equals(url.getScheme());
	}
	
	public URI toHttpUrl(final URI url) throws URISyntaxException {
		if (isPortableUrl(url)) {
			final String path= nonNullElse(url.getPath(), "/"); //$NON-NLS-1$
			final StringBuilder p= new StringBuilder(this.contextPath.length() + path.length() + 2);
			p.append(this.contextPath);
			if (path.isEmpty() || path.charAt(0) != '/') {
				p.append('/');
			}
			p.append(path);
			return createHttpUrl(p);
		}
		return url;
	}
	
	protected URI createPortableUrl(final String path) throws URISyntaxException {
		return new URI(PORTABLE_URI_SCHEME, null, null, -1, path, null, null);
	}
	
	public @Nullable URI toPortableUrl(final URI url) throws URISyntaxException {
		if (isDynamicUrl(url)) {
			final String path= getDynamicPath(url);
			return createPortableUrl(path);
		}
		else if (isPortableUrl(url)) {
			return url;
		}
		return null;
	}
	
	
	public @Nullable URI toServerUrl(final URI url) {
		if (isDynamicUrl(url)) {
			final String path= getDynamicPath(url);
			final int targetEnd= path.indexOf('/', 1);
			if (targetEnd > 1
					&& path.substring(1, targetEnd).equals(BROWSE_TARGET)) {
				final int envIdEnd= path.indexOf('/', targetEnd + 1);
				if (envIdEnd > targetEnd + 2) {
					final REnv rEnv= this.rHelpManager.getREnv(path.substring(targetEnd + 1, envIdEnd));
					if (rEnv != null) {
						final REnvHelpConfiguration rEnvConfig= rEnv.get(REnvHelpConfiguration.class);
						if (rEnvConfig != null
								&& rEnvConfig.getStateSharedType() == REnvConfiguration.SHARED_SERVER) {
							try {
								final ServerClientSupport serverSupport= ServerClientSupport.getInstance();
								return serverSupport.toServerBrowseUrl(rEnvConfig,
										path.substring(envIdEnd) );
							}
							catch (final Exception e) {}
						}
					}
				}
			}
		}
		else {
			final String path= url.getPath();
			if (path != null && path.startsWith(RHelpWebapp.CONTEXT_PATH)) {
				return url;
			}
		}
		return null;
	}
	
}
