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

import java.util.regex.Pattern;

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

import org.eclipse.statet.internal.rhelp.core.REnvHelpImpl;


@NonNullByDefault
public class ServerApi {
	
	
	public static final String API_VERSION_1= "api/v1"; //$NON-NLS-1$
	
	public static final String DS_MIME_TYPE= "application/x.org.eclipse.statet.rhelp-ds"; //$NON-NLS-1$
	
	public static final String DS_SER_VERSION= "ser"; //$NON-NLS-1$
	
	public static final String STAMP= "stamp"; //$NON-NLS-1$
	public static final String BASIC_DATA= "basic-data"; //$NON-NLS-1$
	public static final String PKGS= "pkgs"; //$NON-NLS-1$
	public static final String PAGES= "pages"; //$NON-NLS-1$
	public static final String SEARCH= "search"; //$NON-NLS-1$
	
	public static final String TOPICS= "topics"; //$NON-NLS-1$
	
	public static final String PKG_PARAM= "pkg"; //$NON-NLS-1$
	public static final String TOPIC_PARAM= "topic"; //$NON-NLS-1$
	public static final String VERSION_PARAM= "v"; //$NON-NLS-1$
	public static final String TYPE= "type"; //$NON-NLS-1$
	public static final String QUERY_STRING_PARAM= "qs"; //$NON-NLS-1$
	public static final String MAX_FRAGMENTS_PARAM= "maxFragments"; //$NON-NLS-1$
	
	public static final byte END_MATCH= 0;
	public static final byte PAGE_MATCH= 1;
	
	
	public static class RequestInfo {
		
		public final String rEnvId;
		public final int segmentCount;
		public final String[] segments;
		
		public RequestInfo(final String rEnvId, final int segmentCount, final String[] segments) {
			this.rEnvId= rEnvId;
			this.segmentCount= segmentCount;
			this.segments= segments;
		}
		
	}
	
	public static @Nullable RequestInfo extractRequestInfo(final @Nullable String path) {
		if (path != null) {
			final int idx1= path.indexOf('/', 1); // rEnvId
			if (idx1 >= 2) {
				final String envId= path.substring(1, idx1);
				
				final String[] segments= new @NonNull String[6];
				int i= 0;
				int beginIdx= idx1 + 1;
				int stopIdx= path.length();
				if (path.charAt(stopIdx - 1) == '/') {
					stopIdx--;
				}
				while (i < segments.length && beginIdx < stopIdx) {
					final int endIdx= path.indexOf('/', beginIdx);
					if (endIdx == -1 || endIdx == stopIdx) {
						segments[i++]= path.substring(beginIdx, stopIdx);
						return new RequestInfo(envId, i, segments);
					}
					else if (endIdx > beginIdx) {
						segments[i++]= path.substring(beginIdx, endIdx);
						beginIdx= endIdx + 1;
						continue;
					}
					else {
						break;
					}
				}
			}
		}
		return null;
	}
	
	
	public static @Nullable String createETag(final long stamp) {
		return (stamp != REnvHelpImpl.NOT_AVAILABLE_STAMP) ?
				'"' + Long.toUnsignedString(stamp) + '"' :
				null;
	}
	
	public static final Pattern ETAG_PATTERN= Pattern.compile("\"(\\d+)\""); //$NON-NLS-1$
	
	
	private ServerApi() {}
	
	
}
