/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.camel.cdi;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.Event;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.enterprise.util.TypeLiteral;
import javax.inject.Inject;

import org.apache.camel.Consumer;
import org.apache.camel.Endpoint;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.support.DefaultEndpoint;

import static java.util.stream.Collectors.joining;

/**
 * A Camel {@link Endpoint} that bridges the CDI events facility with Camel routes so that CDI events
 * can be seamlessly observed / consumed (respectively produced / fired) from Camel consumers (respectively by Camel producers).<p>
 *
 * The {@code CdiEventEndpoint<T>} bean can be used to observe / consume CDI events whose event type is {@code T}, for example:
 * <pre><code>
 * {@literal @}Inject
 *  CdiEventEndpoint{@literal <}String{@literal >} cdiEventEndpoint;
 *
 *  from(cdiEventEndpoint).log("CDI event received: ${body}");
 * </code></pre>
 *
 * Conversely, the {@code CdiEventEndpoint<T>} bean can be used to produce / fire CDI events whose event type is {@code T}, for example:
 * <pre><code>
 * {@literal @}Inject
 *  CdiEventEndpoint{@literal <}String{@literal >} cdiEventEndpoint;
 *
 *  from("direct:event").to(cdiEventEndpoint).log("CDI event sent: ${body}");
 * </code></pre>
 *
 * The type variable {@code T}, respectively the qualifiers, of a particular {@code CdiEventEndpoint<T>} injection point
 * are automatically translated into the parameterized <i>event type</i>, respectively into the <i>event qualifiers</i>, e.g.:
 * <pre><code>
 * {@literal @}Inject
 * {@literal @}FooQualifier
 *  CdiEventEndpoint{@literal <}List{@literal <}String{@literal >}{@literal >} cdiEventEndpoint;
 *
 *  from("direct:event").to(cdiEventEndpoint);
 *
 *  void observeCdiEvents({@literal @}Observes {@literal @}FooQualifier List{@literal <}String{@literal >} event) {
 *      logger.info("CDI event: {}", event);
 *  }
 * </code></pre>
 */
public final class CdiEventEndpoint<T> extends DefaultEndpoint {

    private final List<CdiEventConsumer<T>> consumers = new ArrayList<>();

    private final Type type;

    private final Set<Annotation> qualifiers;

    private final BeanManager manager;

    CdiEventEndpoint(String endpointUri, Type type, Set<Annotation> qualifiers, BeanManager manager) {
        super(endpointUri, null);
        this.type = type;
        this.qualifiers = qualifiers;
        this.manager = manager;
    }

    static String eventEndpointUri(Type type, Set<Annotation> qualifiers) {
        return "cdi-event://" + authorityFromType(type) + qualifiers.stream()
            .map(CdiSpiHelper::createAnnotationId)
            .collect(joining("%2C", qualifiers.size() > 0 ? "?qualifiers=" : "", ""));
    }

    private static String authorityFromType(Type type) {
        if (type instanceof Class) {
            return Class.class.cast(type).getName();
        }
        if (type instanceof ParameterizedType) {
            return Stream.of(((ParameterizedType) type).getActualTypeArguments())
                .map(CdiEventEndpoint::authorityFromType)
                .collect(joining("%2C", authorityFromType(((ParameterizedType) type).getRawType()) + "%3C", "%3E"));
        }
        if (type instanceof GenericArrayType) {
            return authorityFromType(((GenericArrayType) type).getGenericComponentType()) + "%5B%5D";
        }

        throw new IllegalArgumentException("Cannot create URI authority for event type [" + type + "]");
    }

    Set<Annotation> getQualifiers() {
        return qualifiers;
    }

    Type getType() {
        return type;
    }

    @Override
    public Consumer createConsumer(Processor processor) {
        return new CdiEventConsumer<>(this, processor);
    }

    @Override
    public Producer createProducer() throws IllegalAccessException {
        // FIXME: to be replaced once event firing with dynamic parameterized type
        // is properly supported (see https://issues.jboss.org/browse/CDI-516)
        TypeLiteral<T> literal = new TypeLiteral<T>() {
        };
        for (Field field : TypeLiteral.class.getDeclaredFields()) {
            if (field.getType().equals(Type.class)) {
                field.setAccessible(true);
                field.set(literal, type);
                break;
            }
        }

        InjectionTarget<AnyEvent> target = manager.createInjectionTarget(manager.createAnnotatedType(AnyEvent.class));
        CreationalContext<AnyEvent> ctx = manager.createCreationalContext(null);
        AnyEvent instance = target.produce(ctx);
        target.inject(instance, ctx);
        return new CdiEventProducer<>(this, instance.event
            .select(literal, qualifiers.toArray(new Annotation[0])));
    }

    @Vetoed
    private static class AnyEvent {

        @Any
        @Inject
        private Event<Object> event;
    }

    void addConsumer(CdiEventConsumer<T> consumer) {
        synchronized (consumers) {
            consumers.add(consumer);
        }
    }

    void removeConsumer(CdiEventConsumer<T> consumer) {
        synchronized (consumers) {
            consumers.remove(consumer);
        }
    }

    void notify(T t) {
        synchronized (consumers) {
            consumers.forEach(consumer -> consumer.notify(t));
        }
    }
}
