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

import java.util.ArrayList;
import java.util.Collection;

import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.uml2.uml.Component;
import org.eclipse.uml2.uml.EnumerationLiteral;
import org.eclipse.uml2.uml.Stereotype;

public class MicroServiceUtils {

	private static final String NO_SQL = "noSql";
	static Collection<Component> microservices = new ArrayList<>();

	public static Collection<Component> getMicroservices() {
		return microservices;
	}

	/**
	 * Return true if the class has applied the Microservice Stereotype
	 * 
	 * @author simone punzo
	 * @param classe
	 * @return true if the class has applied the Microservice Stereotype
	 */
	public static boolean hasMicroServiceStereotype(Component component) {

		Stereotype stereotype = component.getAppliedStereotype(StereotypeName.MICROSERVICE);
		if (stereotype != null) {
			return true;
		}

		return false;
	}

	/**
	 * @author Simone Punzo <simone.punzo@micegroup.it>
	 * @param component
	 * @return true if the class has the Gateway stereotype
	 */

	public static boolean hasGatewayStereotype(Component component) {
		Stereotype stereotype = component.getAppliedStereotype(StereotypeName.GATEWAY);
		if (stereotype != null) {
			return true;
		}
		return false;
	}

	/**
	 * Funzione per checkare se un dato componente ha una determinata categoria
	 */
	public static boolean isInCategory(Component aComponent, MicroServiceCategory category) {
		String modelCategory = getCategory(aComponent);

		if (modelCategory != null && category.toString().equals(modelCategory))
			return true;
		return false;
	}

	/**
	 * Funzione per ottenere la categoria di un componente
	 * 
	 * @param model
	 * @return
	 */
	public static String getCategory(Component aComponent) {
		EnumerationLiteral stereotypeValue = StereotypeUtils.<EnumerationLiteral, Component>getStereotypeValue(
				aComponent, StereotypeName.MICROSERVICE, StereotypePropertyName.CATEGORY);
		if (stereotypeValue != null)
			return stereotypeValue.getName();
		return null;
	}

	/**
	 * funzione per ottenere il port number di un component con stereotype
	 * Microservizio
	 * 
	 * @author Simone Punzo <simone.punzo@micegroup.it>
	 * @param aComponent
	 */
	public static Integer getMsPortNumber(Component aComponent) {
		Integer stereotypeValue = StereotypeUtils.<Integer, Component>getStereotypeValue(aComponent,
				StereotypeName.MICROSERVICE, StereotypePropertyName.PORT_NUMBER);
		if (stereotypeValue != null)
			return stereotypeValue;
		return null;
	}

	/**
	 * @author Simone Punzo <simone.punzo@micegroup.it>
	 * @param aComponent
	 * @return the portNumber property of a component with stereotype Gateway
	 */
	public static Integer getGatewayPortNumber(Component aComponent) {
		Integer stereotypeValue = StereotypeUtils.<Integer, Component>getStereotypeValue(aComponent,
				StereotypeName.GATEWAY, StereotypePropertyName.PORT_NUMBER);
		if (stereotypeValue != null)
			return stereotypeValue;
		return null;
	}

	/**
	 * funzione per capire se un componente è un componente di sicurezza
	 * 
	 * @author Simone Punzo <simone.punzo@micegroup.it>
	 * @param aComponent
	 * @return
	 */
	public static boolean isSecurityMS(Component aComponent) {
		return MicroServiceUtils.isInCategory(aComponent, MicroServiceCategory.security);
	}

	/**
	 * funzione per capire se un componente è un componente di notification
	 * 
	 * @author Simone Punzo <simone.punzo@micegroup.it>
	 * @param aComponent
	 * @return
	 */

	public static boolean isNotificationMS(Component aComponent) {
		return MicroServiceUtils.isInCategory(aComponent, MicroServiceCategory.notification);
	}

	/**
	 * funzione per capire se un componente è un componente di attachment
	 * 
	 * @param aComponent
	 * @return
	 */
	public static boolean isAttachmentMS(Component aComponent) {
		return MicroServiceUtils.isInCategory(aComponent, MicroServiceCategory.attachment);
	}

	/**
	 * funzione per capire se un componente è un componente di business
	 * 
	 * @param aComponent
	 * @return
	 */
	public static boolean isBusinessMS(Component aComponent) {
		return MicroServiceUtils.isInCategory(aComponent, MicroServiceCategory.business);
	}

	/**
	 * funzione per capire se un componente è un componente di demo
	 * 
	 * @param aComponent
	 * @return
	 */
	public static boolean isDemoMS(Component aComponent) {
		return MicroServiceUtils.isInCategory(aComponent, MicroServiceCategory.demo);
	}

	/**
	 * Return true if the class has applied the Microservice Stereotype
	 * 
	 * @author simone punzo
	 * @param classe
	 * @return true if the class has applied the Microservice Stereotype
	 */
	public static boolean hasSPAStereotype(Component component) {

		Stereotype stereotype = component.getAppliedStereotype(StereotypeName.SPA);
		if (stereotype != null) {
			return true;
		}

		return false;
	}

	/**
	 * Function to create an unique Id for each microservice Abbiamo una stringa
	 * fill con length=lengthId , la substringhiamo da name.length in modo che la
	 * stringa builder matchi la lunghezza giusta
	 * 
	 * @author Simone Punzo <simone.punzo@micegroup.it>
	 * @return
	 */
	public static String generateRandomModelId(Component microservice) {
		String name = microservice.getName().toString();
		String fill = "V0il4fRaM3WoRKM1cRo5Er";
		StringBuilder builder = new StringBuilder();
		builder.append("_" + name + fill.substring(name.length()));
		return builder.toString();
	}

	/**
	 * Ritorna l'id del Microservizio in input
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 *
	 * @param aComponent
	 * @return
	 */
	public static String getId(Component aComponent) {
		String stereotypeValue = StereotypeUtils.<String, Component>getStereotypeValue(aComponent,
				StereotypeName.MICROSERVICE, StereotypePropertyName.ID);
		if (getMsPortNumber(aComponent) != null && (stereotypeValue == null || stereotypeValue.isEmpty())) {
			return getMsPortNumber(aComponent).toString().substring(2);
		} else if (stereotypeValue != null)
			return stereotypeValue;
		return null;
	}

	/**
	 * Ritorna il tipo di persistence scelto per il microservizio in input
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 *
	 * @param aComponent
	 * @return
	 */
	public static String getPersistenceType(Component aComponent) {
		EnumerationLiteral stereotypeValue = StereotypeUtils.<EnumerationLiteral, Component>getStereotypeValue(
				aComponent, StereotypeName.MICROSERVICE, StereotypePropertyName.PERSISTENCE_TYPE);
		if (stereotypeValue != null)
			return stereotypeValue.getName();
		return null;
	}

	/**
	 * Ritorna true se il microservizio è noSQL
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 *
	 * @param microservice
	 * @return
	 */
	public static boolean isNoSqlMicroservice(Component microservice) {
		if (getPersistenceType(microservice).equals(NO_SQL)) {
			return true;
		}
		return false;
	}
	
	

}
