/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * All rights reserved. This program and the accompanying materials           
 * are made available under the terms of the Eclipse Public License 2.0        
 * which accompanies this distribution, and is available at                  
 * https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 * SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.infogrid.api;

import java.lang.reflect.Field;

import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridProperty;
import org.eclipse.osbp.runtime.common.annotations.DtoUtils;
import org.eclipse.osbp.runtime.common.util.BeanUtils;

public class GridUtil {

	public static boolean isNested(Class<?> rootType, CxGridProperty prop) {
		return prop.getDotPath() != null && prop.getDotPath().contains(".") || isBindsRawDto(rootType, prop);
	}

	public static boolean isNestedAndBindsDto(Class<?> rootType, CxGridProperty prop) {
		if (!isNested(rootType, prop)) {
			return false;
		}

		if (prop.getDotPath().contains(".")) {
			// nested field
			String[] tokens = prop.getDotPath().split("\\.");
			Class<?> nestedType = BeanProperties.value(rootType, tokens[0]).getPropertyDescriptor().getPropertyType();

			// if the first type in the dot path is a dto, we use a combo for
			// editing
			if (IDto.class.isAssignableFrom(nestedType)) {
				return true;
			}
		} else {
			return isBindsRawDto(rootType, prop);
		}
		return false;
	}

	/**
	 * Is used to create groups in the grid. A group is defined by the first dto
	 * in the binding path.<br>
	 * Eg: <br>
	 * <ul>
	 * <li>person.<b>country</b> --> "country"</li>
	 * <li>person.<b>country</b>.isoCode --> "country"</li>
	 * <li>person.<b>country</b>.continent --> "country"</li>
	 * <li>person.<b>country</b>.continent.name --> "country"</li>
	 * </ul>
	 * 
	 * @param rootType
	 * @param prop
	 * @return
	 */
	public static String getGroup(Class<?> rootType, CxGridProperty prop) {
		if (!isNested(rootType, prop)) {
			return "Main";
		}

		Class<?> dtoType = getDtoType(rootType, prop);
		return dtoType.getSimpleName() ;
	}

	/**
	 * Returns true, if the path or dot path points to a dto.<br>
	 * Eg: person.country<br>
	 * In this case the domainKey property will be attached to the dto path
	 * later. <code>person.country --> person.country.isoCode</code>
	 * 
	 * @param rootType
	 * @param prop
	 * @return
	 */
	public static boolean isBindsRawDto(Class<?> rootType, CxGridProperty prop) {

		Class<?> type = BeanUtils.getNestedFieldType(rootType, prop.getDotPath());
		// if the first type in the dot path is a dto, we use a combo for
		// editing
		if (IDto.class.isAssignableFrom(type)) {
			return true;
		}

		return false;
	}

	/**
	 * Returns the dto type, if the path or dot path points to a dto.<br>
	 * Eg: person.country.continent -> continent is returned<br>
	 * 
	 * @param rootType
	 * @param prop
	 * @return
	 */
	public static Class<?> getBindsRawDtoType(Class<?> rootType, CxGridProperty prop) {
		if (!isBindsRawDto(rootType, prop)) {
			throw new IllegalArgumentException("Not a valid call");
		}
		Class<?> type = BeanUtils.getNestedFieldType(rootType, prop.getDotPath());
		return type;
	}

	/**
	 * Returns true, if the path or dot path points to a dto.<br>
	 * Eg: person.country<br>
	 * In this case the domainKey property will be attached to the dto path
	 * later. <code>person.country --> person.country.isoCode</code>
	 * 
	 * @param rootType
	 * @param prop
	 * @return
	 */
	public static boolean isBindsDomainKey(Class<?> rootType, CxGridProperty prop) {
		if (isBindsRawDto(rootType, prop)) {
			return false;
		}
		Field field = BeanUtils.getNestedField(rootType, prop.getDotPath());
		String propName = field.getName();

		Class<?> type = field.getDeclaringClass();
		return DtoUtils.isDomainkeyField(type, propName);
	}

	/**
	 * Returns the path which binds the dto. It is used to create a column for
	 * the dto in the grid.<br>
	 * Eg:<br>
	 * Full path: country.continent.name<br>
	 * Dto path: country --> Since country binds the country dto. The tail path
	 * will be continent.name and is used to point the nested converter to the
	 * target property inside the country. country will be added as a column to
	 * the grid.
	 * 
	 * @param rootType
	 * @param prop
	 * @return
	 */
	public static String getDtoBindingPath(Class<?> rootType, CxGridProperty prop) {
		if (!isNestedAndBindsDto(rootType, prop)) {
			return prop.getDotPath();
		}

		String[] tokens = prop.getDotPath().split("\\.");
		return tokens[0];
	}

	/**
	 * Returns the tail dot path used to point the NestedConverter to its
	 * property inside the dto.<br>
	 * Eg:<br>
	 * Full path: country.continent.name<br>
	 * Tail path: continent.name --> Since country binds the country dto. So
	 * country will be added as a column to the grid.
	 * 
	 * @param rootType
	 * @param prop
	 * @return
	 */
	public static String getNestedConverterTailDotPath(Class<?> rootType, CxGridProperty prop) {
		if (!isNestedAndBindsDto(rootType, prop)) {
			return prop.getDotPath();
		}

		String[] tokens = prop.getDotPath().split("\\.");
		if (tokens.length == 1) {
			return "";
		}
		StringBuilder b = new StringBuilder();
		for (int i = 1; i < tokens.length; i++) {
			if (b.length() != 0) {
				b.append(".");
			}
			b.append(tokens[i]);
		}
		return b.toString();
	}

	public static Class<?> getDtoType(Class<?> rootType, CxGridProperty prop) {
		return BeanProperties.value(rootType, getDtoBindingPath(rootType, prop)).getPropertyDescriptor()
				.getPropertyType();
	}
	
	public static Class<?> getPropertyType(Class<?> rootType, CxGridProperty prop) {
		return BeanProperties.value(rootType, prop.getDotPath()).getPropertyDescriptor()
				.getPropertyType();
	}

	public static String getDomainKeyName(Class<?> rootType, CxGridProperty prop) {
		if (!isBindsRawDto(rootType, prop)) {
			throw new IllegalStateException("Only dtos have domainkeys");
		}
		
		Class<?> type = getBindsRawDtoType(rootType, prop);
		return DtoUtils.getDomainKeyField(type).getName();
	}

}
