/********************************************************************************
 * Copyright (c) 2015-2020 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 ********************************************************************************/

package org.eclipse.mdm.businessobjects.utils;

import java.lang.reflect.Method;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.eclipse.mdm.api.base.ServiceNotProvidedException;
import org.eclipse.mdm.api.base.adapter.Core;
import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.adapter.ModelManager;
import org.eclipse.mdm.api.base.model.BaseEntity;
import org.eclipse.mdm.api.base.model.ContextRoot;
import org.eclipse.mdm.api.base.model.ContextType;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.Environment;
import org.eclipse.mdm.api.base.model.ValueType;
import org.eclipse.mdm.api.base.query.ComparisonOperator;
import org.eclipse.mdm.api.base.query.Condition;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.FilterItem;
import org.eclipse.mdm.api.dflt.ApplicationContext;
import org.eclipse.mdm.api.dflt.EntityManager;
import org.eclipse.mdm.api.dflt.model.*;
import org.eclipse.mdm.businessobjects.control.FilterParser;
import org.eclipse.mdm.businessobjects.entity.I18NResponse;
import org.eclipse.mdm.businessobjects.entity.MDMEntityResponse;
import org.eclipse.mdm.businessobjects.entity.SearchAttributeResponse;
import org.eclipse.mdm.businessobjects.service.EntityService;
import org.slf4j.LoggerFactory;

import io.vavr.Value;
import io.vavr.collection.Map;
import io.vavr.collection.Stream;
import io.vavr.control.Try;

public final class ServiceUtils {

	private ServiceUtils() {
	}

	/**
	 * returns true if the given filter String is a parent filter of the given
	 * parent type
	 *
	 * @param em         {@link EntityManager} of the data source
	 * @param filter     parent filter string to check
	 * @param parentType class of the parent entity
	 * @return true if the give filter String is a parent filter
	 */
	public static boolean isParentFilter(ApplicationContext context, String filter,
			Class<? extends Entity> parentType) {
		ModelManager mm = context.getModelManager()
				.orElseThrow(() -> new ServiceNotProvidedException(ModelManager.class));
		EntityType et = mm.getEntityType(parentType);

		Filter f = FilterParser.parseFilterString(mm.listEntityTypes(), filter);

		List<FilterItem> filterItems = f.stream().collect(Collectors.toList());

		if (filterItems.size() == 1 && filterItems.get(0).isCondition()) {
			Condition c = filterItems.get(0).getCondition();
			return et.getIDAttribute().equals(c.getAttribute())
					&& ComparisonOperator.EQUAL.equals(c.getComparisonOperator());
		} else {
			return false;
		}
	}

	/**
	 * returns the business object ID from a parent filter
	 *
	 * @param em         {@link EntityManager} of the data source
	 * @param filter     parent filter string
	 * @param parentType parent type to identify the Id attribute name
	 * @return the extracted business object Id
	 * @throws IllegalArgumentException if the given filter is not a parent filter,
	 *                                  this means the filter does not have exactly
	 *                                  one condition on the parent's ID attribute
	 *                                  with {@link ComparisonOperator#EQUAL}
	 */
	public static String extactIdFromParentFilter(ApplicationContext context, String filter,
			Class<? extends Entity> parentType) {
		ModelManager mm = context.getModelManager()
				.orElseThrow(() -> new ServiceNotProvidedException(ModelManager.class));
		EntityType et = mm.getEntityType(parentType);

		Filter f = FilterParser.parseFilterString(mm.listEntityTypes(), filter);

		List<FilterItem> filterItems = f.stream().collect(Collectors.toList());

		if (filterItems.size() == 1 && filterItems.get(0).isCondition()) {
			Condition c = filterItems.get(0).getCondition();
			if (et.getIDAttribute().equals(c.getAttribute())
					&& ComparisonOperator.EQUAL.equals(c.getComparisonOperator())) {
				return c.getValue().extract(ValueType.STRING);
			}
		}

		throw new IllegalArgumentException("Cannot extract parent ID. Filter is not a parent filter: " + filter);
	}

	/**
	 * Simple workaround for naming mismatch between Adapter and Business object
	 * names.
	 * 
	 * @param entityType entity type
	 * @return MDM business object name
	 */
	public static String workaroundForTypeMapping(EntityType entityType) {
		switch (entityType.getName()) {
		case "StructureLevel":
			return "Pool";
		case "MeaResult":
			return "Measurement";
		case "SubMatrix":
			return "ChannelGroup";
		case "MeaQuantity":
			return "Channel";
		default:
			return entityType.getName();
		}
	}

	/**
	 * Builds {@Link Response} from given {@link Entity}
	 * 
	 * @param entity {@link Entity} to build {@link Response} from
	 * @return the build {@link Response}
	 */
	public static <T extends Entity> Response buildEntityResponse(T entity, Status status) {
		if (entity != null) {
			MDMEntityResponse response = new MDMEntityResponse(entity.getClass(), entity);
			// TODO anehmer on 2018-02-08: relations should be included in the output
			GenericEntity<Object> genEntity = new GenericEntity<>(response, response.getClass());
			return Response.status(status).entity(genEntity).type(MediaType.APPLICATION_JSON).build();
		} else {
			return Response.status(Status.NO_CONTENT).type(MediaType.APPLICATION_JSON).build();
		}
	}

	/**
	 * Builds {@Link Response} from given {@link Entity}
	 * 
	 * @param entity {@link Entity} to build {@link Response} from
	 * @return the build {@link Response} or empty response if entities is empty
	 */
	public static <T extends Entity> Response buildEntityResponse(io.vavr.collection.List<T> entities, Status status) {
		if (entities.nonEmpty()) {
			@SuppressWarnings("unchecked")
			Class<T> entityClass = (Class<T>) entities.get().getClass();
			MDMEntityResponse response = new MDMEntityResponse(entityClass, entities.asJava());
			GenericEntity<Object> genEntity = new GenericEntity<>(response, response.getClass());
			return Response.status(status).entity(genEntity).type(MediaType.APPLICATION_JSON).build();
		} else {
			return Response.status(Status.NO_CONTENT).type(MediaType.APPLICATION_JSON).build();
		}
	}

	/**
	 * Builds {@Link Response} from given {@link Entity}
	 * 
	 * @param entity {@link Entity} to build {@link Response} from
	 * @param clazz  default class of entity. Used for empty collections.
	 * @return the build {@link Response}
	 */
	@SuppressWarnings("unchecked")
	public static <T extends Entity> Response buildEntityResponse(io.vavr.collection.List<T> entities, Status status,
			Class<T> clazz) {

		if (entities != null) {
			Class<T> entityClass;
			if (entities.nonEmpty()) {
				entityClass = (Class<T>) entities.get().getClass();
			} else {
				entityClass = clazz;
			}
			MDMEntityResponse response = new MDMEntityResponse(entityClass, entities.asJava());
			GenericEntity<Object> genEntity = new GenericEntity<>(response, response.getClass());
			return Response.status(status).entity(genEntity).type(MediaType.APPLICATION_JSON).build();
		} else {
			return Response.status(Status.NO_CONTENT).type(MediaType.APPLICATION_JSON).build();
		}
	}

	/**
	 * Builds {@Link Response} from given {@link Entity}
	 * 
	 * @param entity {@link Entity} to build {@link Response} from
	 * @return the build {@link Response}
	 */
	public static <T extends Entity> Response buildErrorResponse(Throwable t, Status status) {
		return Response.status(status).entity(t).type(MediaType.APPLICATION_JSON).build();
	}

	/**
	 * Converts the given object to a {@link Response} with the given {@link Status}
	 *
	 * @param response object to convert
	 * @param status   {@link Status} of the {@link Response}
	 * @return the created {@link Response}
	 */
	public static Response toResponse(Object response, Status status) {
		GenericEntity<Object> genEntity = new GenericEntity<>(response, response.getClass());
		return Response.status(status).entity(genEntity).type(MediaType.APPLICATION_JSON).build();
	}

	/**
	 * Return the search attributes for the {@link ValueList} type.
	 * 
	 * @param sourceNameSupplier {@link Value} with the name of the source (MDM
	 *                           {@link org.eclipse.mdm.api.base.model.Environment}
	 *                           name)
	 * @param entityClass        {@link Entity} class to get localization data for
	 * @param entityService      {@link EntityService} used to get localization data
	 * @return the result of the delegated request as {@link Response}
	 */
	public static <T extends Entity> Response buildSearchAttributesResponse(Value<String> sourceNameSupplier,
			Class<T> entityClass, EntityService entityService) {
		return entityService.getSearchAttributesSupplier(sourceNameSupplier, entityClass)
				.map(searchAttributes -> ServiceUtils
						.toResponse(new SearchAttributeResponse(searchAttributes.toJavaList()), Status.OK))
				.recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
	}

	/**
	 * Return the localized type and attributes for the {@link Entity} type.
	 * 
	 * @param sourceNameSupplier {@link Value} with the name of the source (MDM
	 *                           {@link Environment} name)
	 * @param entityClass        {@link Entity} class to get localization data for
	 * @param entityService      {@link EntityService} used to get localization data
	 * @return the {@link Response} with the localized data
	 */
	public static <T extends Entity> Response buildLocalizationResponse(Value<String> sourceNameSupplier,
			Class<T> entityClass, EntityService entityService) {
		return Try.of(() -> ServiceUtils.toResponse(
				new I18NResponse(
						entityService.getLocalizeTypeSupplier(sourceNameSupplier, entityClass).get().toJavaMap(),
						entityService.getLocalizeAttributesSupplier(sourceNameSupplier, entityClass).get().toJavaMap()),
				Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
	}

	/**
	 * A Response representing a server error.
	 */
	public static final Response SERVER_ERROR_RESPONSE = Response.serverError().build();

	/**
	 * Builds an error response based on an exception to be sent to the client
	 */
	public static final Function<? super Throwable, Response> ERROR_RESPONSE_SUPPLIER = e -> {
		LoggerFactory.getLogger(ServiceUtils.class).error(e.getMessage(), e);
		// TODO anehmer on 2017-11-22: customize status according to exception
		return Response
				.status(Status.INTERNAL_SERVER_ERROR).entity(e.getStackTrace()[0].getClassName() + "."
						+ e.getStackTrace()[0].getMethodName() + ": " + e.getMessage())
				.type(MediaType.APPLICATION_JSON).build();
	};

	/**
	 * Returns a {@link Try} to get the {@link ContextType} for the provided name
	 * 
	 * @param contextTypeName name of the {@link ContextType}
	 * @return a {@link Try} of the {@link ContextType} for the given name
	 */
	public static Try<ContextType> getContextTypeSupplier(String contextTypeName) {
		return Stream.of(ContextType.values())
				.filter(contextType -> contextType.name().equals(contextTypeName.toUpperCase())).toTry();
	}

	/**
	 * Converts vavr style context map to java.util style context map
	 */
	public static java.util.Map<String, java.util.Map<ContextType, ContextRoot>> contextMapToJava(
			Map<String, Map<ContextType, ContextRoot>> ctx) {
		return ctx.bimap(s -> s, m -> m.toJavaMap()).toJavaMap();
	}

	/**
	 * Get {@link ContextType} from given entity if it has one. Otherwise return
	 * null.
	 * 
	 * @param entity {@link Entity} to get {@link ContextType} for
	 * @return {@link ContextType} or null
	 */
	public static ContextType getContextType(Entity entity) {
		if (entity instanceof CatalogAttribute) {
			return ((CatalogAttribute) entity).getCatalogComponent().map(CatalogComponent::getContextType)
					.orElseGet(null);
		} else if (entity instanceof CatalogComponent) {
			return ((CatalogComponent) entity).getContextType();
		} else if (entity instanceof TemplateRoot) {
			return ((TemplateRoot) entity).getContextType();
		} else if (entity instanceof TemplateComponent) {
			return ((TemplateComponent) entity).getTemplateRoot().getContextType();
		} else if (entity instanceof TemplateAttribute) {
			return ((TemplateAttribute) entity).getTemplateComponent().map(TemplateComponent::getTemplateRoot)
					.map(TemplateRoot::getContextType).orElseGet(null);
		}

		return null;
	}

	/**
	 * Get the {@link org.eclipse.mdm.api.base.adapter.Core} of given
	 * {@link org.eclipse.mdm.api.base.model.Entity}
	 * 
	 * @param e Entity to get Core of
	 * @return Core of given Entity
	 */
	public static Core getCore(Entity e) {
		return Try.of(() -> {
			Method getMetod;
			try {
				getMetod = BaseEntity.class.getDeclaredMethod("getCore");
				getMetod.setAccessible(true);
			} catch (NoSuchMethodException | SecurityException x) {
				throw new IllegalStateException(
						"Unable to load 'getCore()' in class '" + BaseEntity.class.getSimpleName() + "'.", x);
			}
			return (Core) getMetod.invoke(e);
		}).get();
	}

}
