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

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


@NonNullByDefault
public class RHelpWebapp {
	
	public static final String CONTEXT_PATH= "/rhelp"; //$NON-NLS-1$
	
	public static final String IMAGES= "images"; //$NON-NLS-1$
	
	public static final String CAT_LIBRARY= "library"; //$NON-NLS-1$
	public static final String CAT_DOC= "doc"; //$NON-NLS-1$
	
	public static final String LIBRARY_HTML= "html"; //$NON-NLS-1$
	public static final String LIBRARY_HELP= "help"; //$NON-NLS-1$
	public static final String LIBRARY_DOC= "doc"; //$NON-NLS-1$
	public static final String LIBRARY_DESCRIPTION= "description"; //$NON-NLS-1$
	
	public static final byte PKGCMD_IDX= 1;
	public static final byte PKGCMD_HTML_PAGE= 2;
	public static final byte PKGCMD_HTML_RESOURCE= 3;
	public static final byte PKGCMD_TOPIC= 4;
	public static final byte PKGCMD_DOC_IDX= 5;
	public static final byte PKGCMD_DOC_RES= 6;
	public static final byte PKGCMD_DESCRIPTION_RES= 7;
	
	public static final String HTML_BEGIN_EXAMPLES= "<!-- BEGIN-EXAMPLES -->"; //$NON-NLS-1$
	public static final String HTML_END_EXAMPLES= "<!-- END-EXAMPLES -->"; //$NON-NLS-1$
	
	public static final String PAR_QUERY_STRING= "qs"; //$NON-NLS-1$
	public static final String PAR_ACTION= "action"; //$NON-NLS-1$
	
	public static final String ACTION_OPEN= "open"; //$NON-NLS-1$
	
	
	@NonNullByDefault ({})
	public static class RequestInfo {
		
		public final String rEnvId;
		public final @Nullable String cat;
		public final byte cmd;
		public final String pkgName;
		public final String detail;
		
		public RequestInfo(final String rEnvId, final String cat, final String detail) {
			this.rEnvId= rEnvId;
			this.cat= cat;
			this.cmd= 0;
			this.pkgName= null;
			this.detail= detail;
		}
		
		public RequestInfo(final String rEnvId, final String cat,
				final byte command, final String pkgName, final String detail) {
			this.rEnvId= rEnvId;
			this.cat= cat;
			this.cmd= command;
			this.pkgName= pkgName;
			this.detail= detail;
		}
		
		public RequestInfo(final String rEnvId) {
			this.rEnvId= rEnvId;
			this.cat= null;
			this.cmd= 0;
			this.pkgName= null;
			this.detail= null;
		}
		
		
	}
	
	public static @Nullable RequestInfo extractRequestInfo(final @Nullable String path) {
		if (path != null) {
			int beginIdx= 1; // rEnvId
			int endIdx= path.indexOf('/', beginIdx);
			if (endIdx > beginIdx) {
				final String envId= path.substring(beginIdx, endIdx);
				beginIdx= endIdx + 1; // cat
				endIdx= path.indexOf('/', beginIdx);
				if (endIdx != -1) {
					String detail;
					switch (path.substring(beginIdx, endIdx)) {
					
					case CAT_DOC:
						beginIdx= endIdx + 1;
						detail= path.substring(beginIdx).replace('\\', '/');
						if (detail.startsWith("/")) {
							detail= detail.substring(1);
						}
						return new RequestInfo(envId, CAT_DOC, detail);
					
					case CAT_LIBRARY: {
						beginIdx= endIdx + 1; // package
						endIdx= path.indexOf('/', beginIdx);
						if (endIdx > beginIdx) {
							final String pkgName= path.substring(beginIdx, endIdx);
							
							beginIdx= endIdx + 1; // cmd
							endIdx= path.indexOf('/', beginIdx);
							if (endIdx == -1) {
								switch (path.substring(beginIdx, path.length())) {
								case LIBRARY_DESCRIPTION:
									return new RequestInfo(envId, CAT_LIBRARY,
											PKGCMD_DESCRIPTION_RES, pkgName, null );
								default:
									return new RequestInfo(envId, CAT_LIBRARY,
											PKGCMD_IDX, pkgName, null);
								}
							}
							if (endIdx > beginIdx) {
								detail= path.substring(endIdx + 1);
								
								switch (path.substring(beginIdx, endIdx)) {
								case LIBRARY_HTML:
									if (detail.indexOf('/', 0) == -1) {
										if (detail.endsWith(".html")) {
											detail= detail.substring(0, detail.length() - 5);
										}
										return new RequestInfo(envId, CAT_LIBRARY,
												PKGCMD_HTML_PAGE, pkgName, detail );
									}
									else {
										return new RequestInfo(envId, CAT_LIBRARY,
												PKGCMD_HTML_RESOURCE, pkgName, detail );
									}
								case LIBRARY_HELP:
									if (detail.endsWith(".html")) {
										detail= detail.substring(0, detail.length() - 5);
									}
									return new RequestInfo(envId, CAT_LIBRARY,
											PKGCMD_TOPIC, pkgName, detail );
								case LIBRARY_DOC:
									if (detail.isEmpty() || detail.equals("index.html")) {
										return new RequestInfo(envId, CAT_LIBRARY,
												PKGCMD_DOC_IDX, pkgName, null );
									}
									return new RequestInfo(envId, CAT_LIBRARY,
											PKGCMD_DOC_RES, pkgName, detail );
								}
							}
						}
					}
					}
				}
				
				return new RequestInfo(envId);
			}
		}
		return null;
	}
	
}
