package org.eclipse.basyx.vab.modelprovider.generic;

import java.util.function.Function;

import org.eclipse.basyx.vab.exception.provider.NotAnInvokableException;
import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException;
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;

/**
 * A generic VAB model provider.
 * 
 * @author espen
 */
public class VABModelProvider implements IModelProvider {
	/**
	 * Handler, which handles single element objects
	 */
	private IVABElementHandler handler;

	/**
	 * Root object that stores contained elements
	 */
	protected Object elements;

	public VABModelProvider(Object elements, IVABElementHandler handler) {
		this.handler = handler;
		this.elements = elements;
	}

	@Override
	public Object getModelPropertyValue(String path) {
		Object element = getTargetElement(path);
		return handler.postprocessObject(element);
	}

	@Override
	public void setModelPropertyValue(String path, Object newValue) {
		VABPathTools.checkPathForNull(path);
		if (VABPathTools.isEmptyPath(path)) {
			// Empty path => parent element == null => replace root, if it exists
			if (elements != null) {
				elements = newValue;
			}
			return;
		}

		Object parentElement = getParentElement(path);
		String propertyName = VABPathTools.getLastElement(path);
		// Throws an exception, if the element does not exist
		handler.getElementProperty(parentElement, propertyName);
		// => Can only set elements that have already been created
		handler.setModelPropertyValue(parentElement, propertyName, newValue);
	}

	@Override
	public void createValue(String path, Object newValue) {
		VABPathTools.checkPathForNull(path);
		if (VABPathTools.isEmptyPath(path)) {
			// The complete model should be replaced if it does not exist
			if (elements == null) {
				elements = newValue;
			} else {
				throw new ResourceAlreadyExistsException("Root element does already exist.");
			}
			return;
		}

		// Find parent & name of new element
		Object parentElement = getParentElement(path);
		String propertyName = VABPathTools.getLastElement(path);
		try {
			Object childElement = handler.getElementProperty(parentElement, propertyName);
			// The last path element does exist -> create the new value here
			handler.createValue(childElement, newValue);
		} catch (ResourceNotFoundException e) {
			// The last path element does not exist
			// -> create the new property in the parent element
			handler.setModelPropertyValue(parentElement, propertyName, newValue);
		}
	}

	@Override
	public void deleteValue(String path) {
		VABPathTools.checkPathForNull(path);

		Object parentElement = getParentElement(path);
		String propertyName = VABPathTools.getLastElement(path);
		handler.deleteValue(parentElement, propertyName);
	}

	@Override
	public void deleteValue(String path, Object obj) {
		Object targetElement = getTargetElement(path);
		handler.deleteValue(targetElement, obj);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Object invokeOperation(String path, Object... parameters) {
		Object childElement = getModelPropertyValue(path);

		// Invoke operation for function interfaces
		if (childElement instanceof Function<?, ?>) {
			Function<Object[], Object> function = (Function<Object[], Object>) childElement;
			return function.apply(parameters);
		} else {
			throw new NotAnInvokableException("Element \"" + path + "\" is not a function.");
		}
	}

	/**
	 * Get the parent of an element in this provider. The path should include the path to the element separated by '/'.
	 * E.g., for accessing element c in path a/b, the path should be a/b/c.
	 */
	private Object getParentElement(String path) {
		VABPathTools.checkPathForNull(path);

		// Split path into its elements, separated by '/'
		String[] pathElements = VABPathTools.splitPath(path);

		Object currentElement = elements;
		// ignore the leaf element, only return the leaf's parent element
		for (int i = 0; i < pathElements.length - 1; i++) {
			currentElement = handler.getElementProperty(currentElement, pathElements[i]);
		}

		if (currentElement == null) {
			throw new ResourceNotFoundException("Parent element for \"" + path + "\" does not exist.");
		}

		return currentElement;
	}


	/**
	 * Instead of returning the parent element of a path, this function gives the target element.
	 * E.g., it returns c for the path a/b/c
	 */
	protected Object getTargetElement(String path) {
		VABPathTools.checkPathForNull(path);
		if (VABPathTools.isEmptyPath(path)) {
			return elements;
		}

		Object parentElement = getParentElement(path);
		String operationName = VABPathTools.getLastElement(path);
		if (operationName != null) {
			return handler.getElementProperty(parentElement, operationName);
		}
		return null;
	}
}
