/*******************************************************************************
 * Copyright (C) 2021 the Eclipse BaSyx Authors
 * 
 * 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/
 * 
 * SPDX-License-Identifier: EPL-2.0
 ******************************************************************************/
package org.eclipse.basyx.vab.modelprovider;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;

/**
 * Utility functions to handle a VAB path
 * 
 * @author kuhn, espen
 * 
 */
public class VABPathTools {
	public static final String SEPERATOR = "/";

	/**
	 * Removes leading and trailing slashes
	 * 
	 * @param path
	 * @return
	 */
	public static String stripSlashes(String path) {
		while (path.startsWith("/")) {
			path = path.substring(1);
		}

		while (path.endsWith("/")) {
			path = path.substring(0, path.length() - 1);
		}
		return path;
	}

	/**
	 * Encodes sensitive characters, e.g. "/" and "#"
	 * 
	 * @param elem
	 * @return
	 */
	public static String encodePathElement(String elem) {
		try {
			return URLEncoder.encode(elem, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * Decodes sensitive characters, e.g. "/" and "#"
	 * 
	 * @param elem
	 * @return
	 */
	public static String decodePathElement(String encodedElem) {
		try {
			return URLDecoder.decode(encodedElem, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * Skips the first N entries of a path. E.g. for <i>a/b/c</i> skipping 2 means
	 * returning <i>c</i>
	 * 
	 * @param path
	 * @param toSkip
	 * @return
	 */
	public static String skipEntries(String path, int toSkip) {
		StringBuilder builder = new StringBuilder();
		String[] splitted = VABPathTools.splitPath(path);

		for (int i = toSkip; i < splitted.length; i++) {
			builder.append(splitted[i]);

			// Don't add slash at last step
			if (i < splitted.length - 1) {
				builder.append("/");
			}

		}

		return builder.toString();
	}

	/**
	 * Returns the Nth entry of a path, e.g. the second entry of <i>a/b/c</i> is
	 * <i>c</i>
	 * 
	 * @param path
	 * @param entry
	 * @return
	 */
	public static String getEntry(String path, int entry) {
		return VABPathTools.splitPath(path)[entry];
	}

	/**
	 * Split a path into path elements, e.g. /a/b/c -> [ a, b, c ]
	 */
	public static String[] splitPath(String path) {
		// Return null result for null argument
		if (path == null) {
			return null;
		}

		// includes null-values, "" and "/";
		if (VABPathTools.isEmptyPath(path)) {
			return new String[] {};
		}

		// Remove leading separator, otherwise /a leads to {"", "a"}
		String fixedPath = removePrefix(path, SEPERATOR);

		String[] splitted = fixedPath.split(SEPERATOR);
		List<String> nonEmptySplitted = new ArrayList<>();

		// Remove empty entries
		for (String s : splitted) {
			if (!s.isEmpty()) {
				nonEmptySplitted.add(s);
			}
		}
		return nonEmptySplitted.toArray(new String[nonEmptySplitted.size()]);
	}

	/**
	 * Remove the last element from the path
	 */
	public static String getParentPath(String path) {
		// Return null result for null argument
		if (path == null) {
			return null;
		}

		if (isEmptyPath(path)) {
			return "";
		}
		int lastIndex = path.lastIndexOf(SEPERATOR);
		if (lastIndex == path.length() - 1) {
			lastIndex = path.lastIndexOf(SEPERATOR, path.length() - 2);
		}
		if (lastIndex >= 0) {
			return removePrefix(path.substring(0, lastIndex), SEPERATOR);
		} else {
			return "";
		}
	}

	/**
	 * Get the last element of a path. Return "" if there is no element in the path
	 */
	public static String getLastElement(String path) {
		// Return null result for null argument
		if (path == null) {
			return null;
		}

		String[] elements = splitPath(path);
		if (elements.length > 0) {
			return elements[elements.length - 1];
		} else {
			return "";
		}
	}

	/**
	 * Remove prefix from beginning of path
	 */
	public static String removePrefix(String path, String prefix) {
		// Return null result for null argument
		if (path == null) {
			return null;
		}

		if (VABPathTools.isEmptyPath(path)) {
			// same result as for any other "empty" path, like "" and "/"
			return "";
		}
		if (path.startsWith(prefix)) {
			return path.substring(prefix.length());
		} else {
			return path;
		}
	}

	public static String append(String path, String element) {
		// Return null result for null argument
		if (path == null || element == null) {
			return null;
		}

		if (path.lastIndexOf(SEPERATOR) == path.length() - 1) {
			return path + element;
		} else {
			return path + SEPERATOR + element;
		}
	}

	/**
	 * Build and return a path with pathElements[startIndex] as the root element
	 */
	public static String buildPath(String[] pathElements, int startIndex) {
		// Return null result for null argument
		if (pathElements == null) {
			return null;
		}

		if (startIndex >= pathElements.length) {
			return "";
		}

		// This will store the resulting path
		StringBuilder result = new StringBuilder();

		// Build path
		for (int i = startIndex; i < pathElements.length; i++)
			result.append(pathElements[i] + SEPERATOR);

		// Remove last '/'
		result.deleteCharAt(result.length() - 1);

		// Return created path
		return result.toString();
	}

	/**
	 * Check if the path to an VAB elements leads to the invocation of an operation. In this case, the
	 * element path conforms to /aas/submodels/{subModelId}/submodelElements/{operationId}/invoke
	 */
	public static boolean isOperationInvokationPath(String path) {
		// null-Paths are no operation paths
		if (path == null) {
			return false;
		}

		// Split path
		String[] pathElements = splitPath(path);
		
		if(pathElements.length == 0) {
			return false;
		}

		// Check if last path element is "invoke" or "operations" is contained anywhere
		return pathElements[pathElements.length - 1].startsWith(Operation.INVOKE) || isOperationPath(path);
	}

	private static boolean isOperationPath(String path) {
		String lowerCasePath = path.toLowerCase();
		return lowerCasePath.startsWith("operations/") || path.toLowerCase().contains("/operations/");
	}

	/**
	 * Check, if the path does not contain any elements.
	 */
	public static boolean isEmptyPath(String path) {
		return path.equals("") || path.equals("/");
	}

	/**
	 * Gets the first endpoint of a path.
	 * @path 
	 * 		A path that can contain 0..* endpoints.
	 * @return
	 * 		The first address entry of a path. The address entry is the first endpoint combined with a protocol.
	 * 		If there is no protocol defined, the address entry is empty ("").
	 * 		E.g. basyx://127.0.0.1:6998//https://localhost/test/ will return basyx://127.0.0.1:6998, 
	 * 		https://localhost/test//basyx://127.0.0.1:6998/ will return https://localhost/test
	 * 		and http://localhost/test/ will return "". 
	 */
	public static String getFirstEndpoint(String fullPath) {
		// Return null result for null argument
		if (fullPath == null) {
			return null;
		}

		if (isEmptyPath(fullPath) || !fullPath.contains("//")) {
			return "";
		} else {
			String[] splitted = fullPath.split("//");
			return splitted[0] + "//" + splitted[1];
		}
	}

	/**
	 * Removes the first endpoint from a path. See {@link #getAddressEntry}<br/>
	 * @path
	 * @return 
	 * 		The first endpoint. E.g. basyx://127.0.0.1:6998//https://localhost/test/ will return
	 * 		https://localhost/test/.
	 * 
	 */
	public static String removeFirstEndpoint(String fullPath) {
		// Return null result for null argument
		if (fullPath == null) {
			return null;
		}

		if (isEmptyPath(fullPath)) {
			return "";
		} else if (!fullPath.contains("//")) {
			return fullPath;
		} else {
			String firstEndpoint = fullPath.replaceFirst(getFirstEndpoint(fullPath), "");
			if (firstEndpoint.startsWith("//")) {
				firstEndpoint = firstEndpoint.replaceFirst("//", "");
			}
			return firstEndpoint;
		}
	}

	/**
	 * Concatenate two paths
	 */
	public static String concatenatePaths(String... paths) {
		// Return null result for null argument
		if (paths == null || paths.length == 0) {
			return null;
		}

		// Store result
		StringBuffer result = new StringBuffer();

		// Flag that indicates whether processed path segment is first segment
		boolean isFirst = true;

		// Process all path segments
		for (String pathSegment : paths) {
			// Return empty result, if any element is null
			if (pathSegment == null) {
				return null;
			}

			// Remove leading and trailing "/" from pathsegment
			while (pathSegment.endsWith("/"))
				pathSegment = pathSegment.substring(0, pathSegment.length() - 1);
			while (pathSegment.startsWith("/"))
				pathSegment = pathSegment.substring(1);

			// Add path to result; if its first segment, do not split with "'"
			if (!isFirst)
				result.append("/");
			else
				isFirst = false;
			result.append(pathSegment);
		}

		// Return combined path
		return result.toString();
	}
	
	/**
	 * Checks if path is null, if yes throw exception
	 * 
	 * @param path
	 */
	public static void checkPathForNull(String path) throws MalformedRequestException {
		if (path == null) {
			throw new MalformedRequestException("Path is not allowed to be null");
		}
	}
	
	/**
	 * Strips the last path element if it is "invoke"
	 * 
	 * @param path
	 * @return path without last element "invoke" or unchanged path
	 */
	public static String stripInvokeFromPath(String path) {
		
		if(path == null)
			return null;
		
		if(getLastElement(path).startsWith(Operation.INVOKE)) {
			return getParentPath(path);
		}
		
		return path;
	}
	
	/**
	 * Gets the path from a URL
	 * e.g "http://localhost:8080/path/to/test.file" results in "/path/to/test.file"
	 * 
	 * @param url
	 * @return the path from the URL
	 */
	public static String getPathFromURL(String url) {
		if(url == null) {
			return null;
		}
		
		if(url.contains("://")) {
			
			// Find the ":" and and remove the "http://" from the url
			int index = url.indexOf(":") + 3;
			url = url.substring(index);
			
			// Find the first "/" from the URL (now without the "http://") and remove everything before that
			index = url.indexOf("/");
			url = url.substring(index);
			
			// Recursive call to deal with more than one server parts 
			// (e.g. basyx://127.0.0.1:6998//https://localhost/test/)
			return getPathFromURL(url);
		} else {
			// Make sure the path has a / at the start
			if(!url.startsWith("/")) {
				url = "/" + url;
			}
			return url;
		}
	}

	/**
	 * Harmonizes a path so that it will always and with the suffix and no ending
	 * slash (even if the suffix contains one).
	 * 
	 * @param path
	 *            to harmonize
	 * @param suffix
	 *            to check for existance and append if necessary
	 * @return harmonized path
	 */
	public static String harmonizePathWithSuffix(String path, String suffix) {
		String strippedPath = stripSlashes(path);
		String strippedSuffix = stripSlashes(suffix);

		if (strippedPath.endsWith("/" + strippedSuffix)) {
			return strippedPath;
		} else {
			return VABPathTools.concatenatePaths(strippedPath, strippedSuffix);
		}
	}
}
