package it.micegroup.voila2.cartridge.library.javaservice;

import org.eclipse.uml2.uml.Association;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Property;

public class PropertyUtils {

	public static final int MAX_INPUT_LENGTH = 30;

	public static boolean isRequired(Property property) {
		Object result = StereotypeUtils.<Boolean, Property>getStereotypeValue(property, StereotypeName.ATTRIBUTE,
				StereotypePropertyName.IS_REQUIRED);
		if (result == null) {
			return false;
		}
		if ((boolean) result == true) {
			return true;
		}
		return false;
	}

	public static String getPropertyLabel(Property property) {
		return StringUtils.splitCamel(property.getName());
	}

	public static boolean isNumeric(Property property) {
		if (property.getType().getName().equals("Currency") || property.getType().getName().equals("Number")
				|| property.getType().getName().equals("Value") || property.getType().getName().equals("Code"))
			return true;
		return false;
	}

	public static boolean isString(Property property) {
		if (property.getType().getName().equals("String"))
			return true;
		return false;
	}

	public static boolean isDateTime(Property property) {
		if (property.getType().getName().equals("Datetime"))
			return true;
		return false;
	}

	public static boolean isLocalDate(Property property) {
		if (property.getType().getName().equals("LocalDate"))
			return true;
		return false;
	}

	public static boolean isBoolean(Property property) {
		if (property.getType().getName().equals("Flag"))
			return true;
		return false;
	}

	public static String getNaturalLanguageName(Property property) {
		return StringUtils.splitCamel(property.getName());
	}

	public static String getLabel(Property p) {
		if (org.apache.commons.lang3.StringUtils.isNotEmpty(StereotypeUtils.<String, Property>getStereotypeValue(p,
				StereotypeName.ATTRIBUTE, StereotypePropertyName.LABEL))) {
			return StereotypeUtils.<String, Property>getStereotypeValue(p, StereotypeName.ATTRIBUTE,
					StereotypePropertyName.LABEL);
		}
		
		if(AuditableAttributes.createdBy.toString().equals(p.getName())) {
			return "Creato da";
		}
		else if(AuditableAttributes.createdDate.toString().equals(p.getName())) {
			return "Data Creazione";
		}
		else if(AuditableAttributes.lastModifiedBy.toString().equals(p.getName())) {
			return "Ultima modifica da";
		}
		else if(AuditableAttributes.lastModifiedDate.toString().equals(p.getName())) {
			return "Data ultima modifica";
		}
		if (!p.getLabel().equals(p.getName())) {
			return StringUtils.splitCamel(p.getLabel());
		}
		return getNaturalLanguageName(p);
	}

	public static String getTooltip(Property p) {
		if (hasHelp(p)) {
			return getHelp(p);
		}
		if (hasDefinition(p)) {
			return getDefinition(p);
		}
		return getLabel(p);
	}

	public static Boolean hasDefinition(Property p) {
		if (getDefinition(p) == null || getDefinition(p) == "") {
			return false;
		}
		return true;
	}

	/**
	 * Ritorna la definizione data della proprietà in input
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 *
	 * @param p property della quale si vuole conoscere la definizione
	 * @return
	 */
	public static String getDefinition(Property p) {
		return StereotypeUtils.<String, Property>getStereotypeValue(p, StereotypeName.ATTRIBUTE,
				StereotypePropertyName.DEFINITION);
	}

	/**
	 * Ritorna il tipo assegnato in fase di modellazione della property in input
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 *
	 * @param p property della quale si vuole conoscere la definizione
	 * @return
	 */
	public static String getDataType(Property p) {
		return StereotypeUtils.<String, Property>getStereotypeValue(p, StereotypeName.ATTRIBUTE,
				StereotypePropertyName.DATA_TYPE);
	}

	public static Boolean hasHelp(Property p) {
		if (getHelp(p) == null || getHelp(p) == "") {
			return false;
		}
		return true;
	}

	public static String getHelp(Property p) {
		return StereotypeUtils.<String, Property>getStereotypeValue(p, StereotypeName.ATTRIBUTE,
				StereotypePropertyName.HELP);
	}

	/**
	 * Return true if the property has set 0 or 1 as multiplicity
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 * @param property
	 * @return true if the property has set 0 or 1 as multiplicity
	 */
	public static boolean isNMultiplicity(Property property) {
		if (property.getUpper() == -1)
			return true;
		return false;
	}

	/**
	 * Return true if the property has set 0 or 1 as multiplicity
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 * @param property
	 * @return true if the property has set 0 or 1 as multiplicity
	 */
	public static boolean isZeroOneMultiplicity(Property property) {
		if (property.getUpper() == 1 || property.getUpper() == 0)
			return true;
		return false;
	}

	/**
	 * 
	 * Return the column lenght
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 * @param attribute
	 * @return column lenght
	 */
	public static String getPhysicalColumnLenght(Property attribute) {
		return StereotypeUtils.<String, Property>getStereotypeValue(attribute, StereotypeName.ATTRIBUTE,
				StereotypePropertyName.PHYSICAL_LENGTH);
	}

	/**
	 * 
	 * Return the columnDefinition used from JPA to produce SQL for column
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 * @param attribute
	 * @return
	 */
	public static String getColumnDefinition(Property attribute, Class classe) {
		String columnDefinition = "";
		String sqlLength = TypeUtils.getSqlLength(attribute);
		String definition = getDefinition(attribute);
		if (getDataType(attribute) == null || getDataType(attribute).trim().isEmpty()) {
			columnDefinition = TypeUtils.getSqlType(attribute.getType());

			if (sqlLength != null && !sqlLength.isEmpty()) {
				columnDefinition += "(";
				columnDefinition += sqlLength;
				columnDefinition += ")";
			}
//		if(attribute.isID() && EntityUtils.hasAutogeneratedId(classe)) {
//			columnDefinition += " AUTO_INCREMENT";
//		}
//		if (definition != null)
//			columnDefinition += " COMMENT '"
//					+ StringUtils.encodeDDL(StringUtils.removeHtmlTags(getDefinition(attribute))) + "'";
		} else {
			columnDefinition = getDataType(attribute);
		}
		return columnDefinition;

	}

	public static String getParentPropAssName(Property property, Class ownerClass, Association association) {
		return property.getName()
				+ StringUtils.toUpperFirst(AssociationUtils.getParentAssName(association, ownerClass));
	}

	public static String getChildPropAssName(Property property, Class ownerClass, Association association) {
		return property.getName() + StringUtils.toUpperFirst(AssociationUtils.getChildAssName(association, ownerClass));
	}

	public static boolean isDate(Property property) {
		if (property.getType().getName().equals("Date"))
			return true;
		return false;
	}

	/**
	 * Usually attribute name is given by it's name property but when attribute is
	 * derived from a parent entity, its name may be concatenated with Association
	 * name.
	 * 
	 * 
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 *
	 * @param property
	 * @param ownerClass
	 * @param association
	 * @param isParent
	 * @return
	 */
	public static String getAttributeName(Property property, Class ownerClass, Association association,
			Boolean isParent) {
		// Attributo interno
		if (association == null) {
			return property.getName();
		} else {
			// Attributo derivato da classe padre
			if (isParent) {
				return property.getName()
						+ StringUtils.toUpperFirst(AssociationUtils.getParentAssName(association, ownerClass));
				// Attributo derivato da classe figlia
			} else {
				return property.getName()
						+ StringUtils.toUpperFirst(AssociationUtils.getChildAssName(association, ownerClass));
			}
		}
	}

	/**
	 * 
	 * Return the column name
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 * @param attribute
	 * @return column name
	 */
	public static String getPhysicalColumnName(Property attribute) {
		String result = StereotypeUtils.<String, Property>getStereotypeValue(attribute, StereotypeName.ATTRIBUTE,
				StereotypePropertyName.PHYSICAL_COLUMN_NAME);
		if (result == null || result.isBlank()) {
			return StringUtils.camelToUnderscore(attribute.getName());
		}
		return result;

	}

	/**
	 * Check if property is an id.
	 * 
	 * @author Federico Gambardella<federico.gambardella@micegroup.it>
	 * @param property
	 * @return
	 */
	public static boolean isAnID(Property property) {
		return property.isID();
	}

	/**
	 * 
	 * @author Teresa Alomba
	 * @param length
	 * @return
	 */
	public static boolean hasPhysicalLengthGreaterThan(String length) {
		if (length != null) {
			try {
				Integer value = Integer.parseInt(length);
				if (value != null && value > MAX_INPUT_LENGTH) {
					return true;
				}
			} catch (NumberFormatException ne) {
				return false;
			}
		}
		return false;

	}

}
