/*=============================================================================#
 # 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.jcommons.lang.ObjectUtils.nonNullElse;

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 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;
	}
	
}
