/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.aries.cdi.container.internal.container;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.event.Observes;
import javax.enterprise.event.ObservesAsync;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedMember;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.aries.cdi.container.internal.annotated.AnnotatedTypeImpl;
import org.apache.aries.cdi.container.internal.model.BeansModel;
import org.apache.aries.cdi.container.internal.model.ComponentPropertiesModel;
import org.apache.aries.cdi.container.internal.model.ExtendedActivationTemplateDTO;
import org.apache.aries.cdi.container.internal.model.ExtendedComponentTemplateDTO;
import org.apache.aries.cdi.container.internal.model.ExtendedConfigurationTemplateDTO;
import org.apache.aries.cdi.container.internal.model.OSGiBean;
import org.apache.aries.cdi.container.internal.model.ReferenceModel;
import org.apache.aries.cdi.container.internal.model.ReferenceModel.Builder;
import org.apache.aries.cdi.container.internal.util.Annotates;
import org.apache.aries.cdi.container.internal.util.Reflection;
import org.osgi.service.cdi.ComponentType;
import org.osgi.service.cdi.ConfigurationPolicy;
import org.osgi.service.cdi.MaximumCardinality;
import org.osgi.service.cdi.ServiceScope;
import org.osgi.service.cdi.annotations.ComponentProperties;
import org.osgi.service.cdi.annotations.ComponentScoped;
import org.osgi.service.cdi.annotations.FactoryComponent;
import org.osgi.service.cdi.annotations.PID;
import org.osgi.service.cdi.annotations.Reference;
import org.osgi.service.cdi.annotations.SingleComponent;
import org.osgi.service.cdi.reference.BindBeanServiceObjects;
import org.osgi.service.cdi.reference.BindService;
import org.osgi.service.cdi.reference.BindServiceReference;
import org.osgi.service.cdi.runtime.dto.template.ComponentTemplateDTO;

public class Discovery {

	private static final List<Type> BIND_TYPES = Arrays.asList(BindService.class, BindBeanServiceObjects.class, BindServiceReference.class);

	public Discovery(ContainerState containerState) {
		_containerState = containerState;
		_beansModel = _containerState.beansModel();
		_containerTemplate = _containerState.containerDTO().template.components.get(0);
	}

	public void discover() {
		_beansModel.getOSGiBeans().stream().forEach(osgiBean -> {
			osgiBean.found(true);

			AnnotatedType<?> annotatedType = new AnnotatedTypeImpl<>(osgiBean.getBeanClass());

			try {
				String beanName = Annotates.beanName(annotatedType);
				Class<? extends Annotation> beanScope = Annotates.beanScope(annotatedType);
				Map<String, Object> componentProperties = Annotates.componentProperties(annotatedType);
				ServiceScope serviceScope = Annotates.serviceScope(annotatedType);
				List<String> serviceTypes = Annotates.serviceClassNames(annotatedType);

				if (annotatedType.isAnnotationPresent(SingleComponent.class)) {
					doFactoryOrSingleComponent(osgiBean, osgiBean.getBeanClass(), annotatedType, beanName, serviceTypes, serviceScope, componentProperties, ComponentType.SINGLE);
				}
				else if (annotatedType.isAnnotationPresent(FactoryComponent.class)) {
					doFactoryOrSingleComponent(osgiBean, osgiBean.getBeanClass(), annotatedType, beanName, serviceTypes, serviceScope, componentProperties, ComponentType.FACTORY);
				}
				else if (annotatedType.isAnnotationPresent(ComponentScoped.class)) {
					_componentScoped.add(osgiBean);
				}
				else {
					discoverActivations(osgiBean, osgiBean.getBeanClass(), annotatedType, null, beanScope, serviceTypes, serviceScope, componentProperties);
				}
			}
			catch (Exception e) {
				_containerState.error(e);

				return;
			}

			annotatedType.getConstructors().stream().filter(this::isInject).flatMap(annotatedConstructor -> annotatedConstructor.getParameters().stream()).forEach(
				annotatedParameter ->
					processAnnotated(annotatedParameter, annotatedParameter.getBaseType(), Annotates.qualifiers(annotatedParameter), osgiBean)
			);

			annotatedType.getFields().stream().filter(this::isInject).forEach(
				annotatedField ->
					processAnnotated(annotatedField, annotatedField.getBaseType(), Annotates.qualifiers(annotatedField), osgiBean)
			);

			annotatedType.getFields().stream().filter(this::isProduces).forEach(
				annotatedField -> {
					Class<? extends Annotation> beanScope = Annotates.beanScope(annotatedField);
					Map<String, Object> componentProperties = Annotates.componentProperties(annotatedField);
					ServiceScope serviceScope = Annotates.serviceScope(annotatedField);
					List<String> serviceTypes = Annotates.serviceClassNames(annotatedField);

					discoverActivations(osgiBean, osgiBean.getBeanClass(), annotatedField, annotatedField, beanScope, serviceTypes, serviceScope, componentProperties);
				}
			);

			annotatedType.getMethods().stream().forEach(annotatedMethod -> {
				if (isInjectOrProduces(annotatedMethod)) {
					annotatedMethod.getParameters().stream().forEach(
						annotatedParameter -> processAnnotated(annotatedParameter, annotatedParameter.getBaseType(), Annotates.qualifiers(annotatedParameter), osgiBean)
					);

					if (isProduces(annotatedMethod)) {
						Class<? extends Annotation> beanScope = Annotates.beanScope(annotatedMethod);
						Map<String, Object> componentProperties = Annotates.componentProperties(annotatedMethod);
						ServiceScope serviceScope = Annotates.serviceScope(annotatedMethod);
						List<String> serviceTypes = Annotates.serviceClassNames(annotatedMethod);

						discoverActivations(osgiBean, osgiBean.getBeanClass(), annotatedMethod, annotatedMethod, beanScope, serviceTypes, serviceScope, componentProperties);
					}
				}
				else if (isDisposeOrObserves(annotatedMethod)) {
					annotatedMethod.getParameters().subList(1, annotatedMethod.getParameters().size()).stream().forEach(
						annotatedParameter -> processAnnotated(annotatedParameter, annotatedParameter.getBaseType(), Annotates.qualifiers(annotatedParameter), osgiBean)
					);
				}
			});
		});

		postProcessComponentScopedBeans();
	}

	<X> boolean isInject(AnnotatedMember<X> annotatedMember) {
		return (annotatedMember.isAnnotationPresent(Inject.class) && !annotatedMember.isStatic());
	}

	<X> boolean isInjectOrProduces(AnnotatedMember<X> annotatedMember) {
		return (annotatedMember.isAnnotationPresent(Inject.class) && !annotatedMember.isStatic()) ||
			annotatedMember.isAnnotationPresent(Produces.class);
	}

	<X> boolean isProduces(AnnotatedMember<X> annotatedMember) {
		return annotatedMember.isAnnotationPresent(Produces.class);
	}

	<X> boolean isDisposeOrObserves(AnnotatedMethod<X> annotatedMethod) {
		return !annotatedMethod.getParameters().isEmpty() && (annotatedMethod.getParameters().get(0).isAnnotationPresent(Disposes.class) ||
			annotatedMethod.getParameters().get(0).isAnnotationPresent(Observes.class) ||
			annotatedMethod.getParameters().get(0).isAnnotationPresent(ObservesAsync.class));
	}

	<X> void processAnnotated(Annotated annotated, Type injectionPointType, Set<Annotation> qualifiers, OSGiBean osgiBean) {
		if (BIND_TYPES.contains(Reflection.getRawType(annotated.getBaseType()))) {
			Builder builder = new ReferenceModel.Builder(annotated);

			try {
				ReferenceModel referenceModel = builder.type(injectionPointType).build();

				osgiBean.addReference(referenceModel.toDTO());
			}
			catch (Exception e) {
				_containerState.error(e);
			}
		}
		else {
			Reference reference = annotated.getAnnotation(Reference.class);
			ComponentProperties componentProperties = annotated.getAnnotation(ComponentProperties.class);

			if (reference != null) {
				doReference(osgiBean, annotated, injectionPointType, reference, componentProperties);
			}
			else if (componentProperties != null) {
				doComponentProperties(osgiBean, injectionPointType, qualifiers);
			}
		}
	}

	void postProcessComponentScopedBeans() {
		_containerState.containerDTO().template.components.stream().filter(
			template -> template.type != ComponentType.CONTAINER
		).map(
			template -> (ExtendedComponentTemplateDTO)template
		).forEach(
			template -> {

				_componentScoped.forEach(
					osgiBean -> {
						if (osgiBean.getComponent() == null) {
							osgiBean.setComponent(_containerState, template);
						}

						String className = osgiBean.getBeanClass().getName();
						if (!template.beans.contains(className)) {
							template.beans.add(className);
						}
					}
				);
			}
		);
	}

	void doComponentProperties(OSGiBean osgiBean, Type injectionPointType, Set<Annotation> qualifiers) {
		try {
			ComponentPropertiesModel configurationModel = new ComponentPropertiesModel.Builder(
				injectionPointType
			).declaringClass(
				osgiBean.getBeanClass()
			).qualifiers(
				qualifiers
			).build();

			osgiBean.addConfiguration(_containerState, configurationModel.toDTO());
		}
		catch (Exception e) {
			_containerState.error(e);
		}
	}

	void discoverActivations(OSGiBean osgiBean, Class<?> declaringClass, Annotated annotated, AnnotatedMember<?> producer, Class<? extends Annotation> scope, List<String> serviceTypeNames, ServiceScope serviceScope, Map<String, Object> componentProperties) {
		String className = declaringClass.getName();

		if (!_containerTemplate.beans.contains(className)) {
			_containerTemplate.beans.add(className);
		}

		if (!serviceTypeNames.isEmpty()) {
			if (!scope.equals(ApplicationScoped.class) &&
				!scope.equals(Dependent.class)) {

				_containerState.error(
					new IllegalStateException(
						String.format(
							"@Service can only be used on @ApplicationScoped, @Dependent, @SingleComponent, and @FactoryComponent: %s",
							osgiBean.getBeanClass())));

				return;
			}

			ExtendedActivationTemplateDTO activationTemplate = new ExtendedActivationTemplateDTO();
			activationTemplate.cdiScope = scope;
			activationTemplate.declaringClass = declaringClass;
			activationTemplate.producer = producer;
			activationTemplate.properties = componentProperties;
			activationTemplate.scope = serviceScope;
			activationTemplate.serviceClasses = serviceTypeNames;

			_containerTemplate.activations.add(activationTemplate);
		}

		osgiBean.setComponent(_containerState, _containerTemplate);
	}

	void doFactoryOrSingleComponent(
			OSGiBean osgiBean, Class<?> declaringClass, Annotated annotated, String beanName,
			List<String> serviceTypes, ServiceScope serviceScope,
			Map<String, Object> componentProperties, ComponentType componentType) {

		Set<Annotation> qualifiers = Annotates.qualifiers(annotated);
		qualifiers.removeIf(Named.class::isInstance);

		ExtendedComponentTemplateDTO componentTemplate = new ExtendedComponentTemplateDTO();
		componentTemplate.activations = new CopyOnWriteArrayList<>();

		ExtendedActivationTemplateDTO activationTemplate = new ExtendedActivationTemplateDTO();
		activationTemplate.declaringClass = declaringClass;
		activationTemplate.properties = Collections.emptyMap();
		activationTemplate.scope = serviceScope;
		activationTemplate.serviceClasses = serviceTypes;

		componentTemplate.activations.add(activationTemplate);

		componentTemplate.beanClass = declaringClass;
		componentTemplate.qualifiers = qualifiers;
		componentTemplate.beans = new CopyOnWriteArrayList<>();
		componentTemplate.configurations = new CopyOnWriteArrayList<>();
		componentTemplate.name = beanName;
		componentTemplate.properties = componentProperties;
		componentTemplate.references = new CopyOnWriteArrayList<>();
		componentTemplate.type = componentType;

		annotated.getAnnotations(PID.class).stream().forEach(
			PID -> {
				String pid = PID.value();

				ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO();

				configurationTemplate.declaringClass = declaringClass;
				configurationTemplate.maximumCardinality = MaximumCardinality.ONE;
				configurationTemplate.pid = Optional.of(pid).map(
					s -> (s.equals("$") || s.equals("")) ? componentTemplate.name : s
				).orElse(componentTemplate.name);

				if (componentType == ComponentType.SINGLE) {
					configurationTemplate.pid = (pid.equals("$") || pid.equals("")) ? componentTemplate.name : pid;
				}

				configurationTemplate.policy = PID.policy();

				componentTemplate.configurations.add(configurationTemplate);
			}
		);

		if (componentType == ComponentType.SINGLE) {
			if (componentTemplate.configurations.isEmpty()) {
				ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO();

				configurationTemplate.declaringClass = declaringClass;
				configurationTemplate.maximumCardinality = MaximumCardinality.ONE;
				configurationTemplate.pid = componentTemplate.name;
				configurationTemplate.policy = ConfigurationPolicy.OPTIONAL;

				componentTemplate.configurations.add(configurationTemplate);
			}
		}
		else {
			ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO();

			configurationTemplate.declaringClass = declaringClass;
			configurationTemplate.maximumCardinality = MaximumCardinality.MANY;
			configurationTemplate.pid = Optional.ofNullable(
				annotated.getAnnotation(FactoryComponent.class)
			).map(FactoryComponent::value).map(
				v -> (v.equals("$") || v.equals("")) ? componentTemplate.name : v
			).orElse(componentTemplate.name);
			configurationTemplate.policy = ConfigurationPolicy.REQUIRED;

			componentTemplate.configurations.add(configurationTemplate);
		}

		componentTemplate.beans.add(declaringClass.getName());

		_containerState.containerDTO().template.components.add(componentTemplate);

		osgiBean.setComponent(_containerState, componentTemplate);
	}

	void doReference(OSGiBean osgiBean, Annotated annotated, Type injectionPointType, Reference reference, ComponentProperties componentProperties) {
		if (componentProperties != null) {
			_containerState.error(
				new IllegalArgumentException(
					String.format(
						"Cannot use @Reference and @Configuration on the same injection point {}",
						injectionPointType))
			);

			return;
		}

		Builder builder = null;

		if (annotated instanceof AnnotatedParameter) {
			builder = new ReferenceModel.Builder(annotated);
		}
		else {
			builder = new ReferenceModel.Builder(annotated);
		}

		try {
			ReferenceModel referenceModel = builder.type(injectionPointType).build();

			osgiBean.addReference(referenceModel.toDTO());
		}
		catch (Exception e) {
			_containerState.error(e);
		}
	}

	private final BeansModel _beansModel;
	private final Set<OSGiBean> _componentScoped = new HashSet<>();
	private final ComponentTemplateDTO _containerTemplate;
	private final ContainerState _containerState;

}
