/*
 * 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.geronimo.microprofile.opentracing.microprofile.cdi;

import java.lang.reflect.Type;
import java.util.Set;
import java.util.concurrent.ExecutorService;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeforeBeanDiscovery;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.enterprise.inject.spi.WithAnnotations;
import javax.enterprise.inject.spi.configurator.AnnotatedTypeConfigurator;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.Path;

import org.apache.geronimo.microprofile.opentracing.common.config.GeronimoOpenTracingConfig;
import org.apache.geronimo.microprofile.opentracing.common.impl.IdGenerator;
import org.apache.geronimo.microprofile.opentracing.common.microprofile.client.OpenTracingClientRequestFilter;
import org.apache.geronimo.microprofile.opentracing.common.microprofile.client.OpenTracingClientResponseFilter;
import org.apache.geronimo.microprofile.opentracing.common.microprofile.thread.OpenTracingExecutorService;
import org.apache.geronimo.microprofile.opentracing.microprofile.zipkin.CdiZipkinConverter;
import org.apache.geronimo.microprofile.opentracing.microprofile.zipkin.CdiZipkinLogger;
import org.eclipse.microprofile.opentracing.Traced;

import io.opentracing.ScopeManager;

public class OpenTracingExtension implements Extension {

    private GeronimoOpenTracingConfig config;

    private boolean useZipkin;
    private boolean useZipkinLogger;

    void onStart(@Observes final BeforeBeanDiscovery beforeBeanDiscovery) {
        config = GeronimoOpenTracingConfig.create();
        useZipkin = Boolean.parseBoolean(config.read("span.converter.zipkin.active", "true"));
        useZipkinLogger = useZipkin && Boolean.parseBoolean(config.read("span.converter.zipkin.logger.active", "true"));
    }

    void vetoDefaultConfigIfScanned(@Observes final ProcessAnnotatedType<GeronimoOpenTracingConfig> config) {
        if (config.getAnnotatedType().getJavaClass().getName()
                  .equals("org.apache.geronimo.microprofile.opentracing.common.config.DefaultOpenTracingConfig")) {
            config.veto();
        }
    }

    void vetoDefaultScopeManagerIfScanned(@Observes final ProcessAnnotatedType<ScopeManager> manager) {
        if (manager.getAnnotatedType().getJavaClass().getName()
                  .equals("org.apache.geronimo.microprofile.opentracing.common.impl.ScopeManagerImpl")) {
            manager.veto();
        }
    }

    void vetoDefaultIdGeneratorIfScanned(@Observes final ProcessAnnotatedType<IdGenerator> generator) {
        if (generator.getAnnotatedType().getJavaClass().getName()
                  .equals("org.apache.geronimo.microprofile.opentracing.common.impl.IdGenerator")) {
            generator.veto();
        }
    }

    void vetoClientRequestTracingIfScanned(@Observes final ProcessAnnotatedType<OpenTracingClientRequestFilter> clientFilter) {
        if (clientFilter.getAnnotatedType().getJavaClass().getName()
                  .equals("org.apache.geronimo.microprofile.opentracing.common.microprofile.client.OpenTracingClientRequestFilter")) {
            clientFilter.veto();
        }
    }

    void vetoClientResponseTracingIfScanned(@Observes final ProcessAnnotatedType<OpenTracingClientResponseFilter> clientFilter) {
        if (clientFilter.getAnnotatedType().getJavaClass().getName()
                  .equals("org.apache.geronimo.microprofile.opentracing.common.microprofile.client.OpenTracingClientResponseFilter")) {
            clientFilter.veto();
        }
    }

    void zipkinConverterToggle(@Observes final ProcessAnnotatedType<CdiZipkinConverter> onZipkinConverter) {
        if (!useZipkin) {
            onZipkinConverter.veto();
        }
    }

    void zipkinLoggerToggle(@Observes final ProcessAnnotatedType<CdiZipkinLogger> onZipkinLogger) {
        if (!useZipkinLogger) {
            onZipkinLogger.veto();
        }
    }

    <T> void removeTracedFromJaxRsEndpoints(@Observes @WithAnnotations(Traced.class) final ProcessAnnotatedType<T> pat) {
        if (isJaxRs(pat.getAnnotatedType())) { // we have filters with more accurate timing
            final AnnotatedTypeConfigurator<T> configurator = pat.configureAnnotatedType();
            configurator.remove(it -> it.annotationType() == Traced.class);
            configurator.methods().stream().filter(m -> isJaxRs(m.getAnnotated()))
                    .forEach(m -> m.remove(it -> it.annotationType() == Traced.class));
        }
    }

    <T> void instrumentExecutorServices(@Observes final ProcessAnnotatedType<T> pat) {
        final Set<Type> typeClosure = pat.getAnnotatedType().getTypeClosure();
        if (typeClosure.contains(ExecutorService.class) && !typeClosure.contains(OpenTracingExecutorService.class)) {
            pat.configureAnnotatedType().add(TracedExecutorService.Literal.INSTANCE);
        }
    }

    void addConfigAsBean(@Observes final AfterBeanDiscovery afterBeanDiscovery) {
        afterBeanDiscovery.addBean().id(OpenTracingExtension.class.getName() + "#" + GeronimoOpenTracingConfig.class.getName())
                .beanClass(GeronimoOpenTracingConfig.class).types(GeronimoOpenTracingConfig.class, Object.class)
                .qualifiers(Default.Literal.INSTANCE, Any.Literal.INSTANCE).scope(ApplicationScoped.class)
                .createWith(ctx -> config);
    }

    private <T> boolean isJaxRs(final AnnotatedType<T> annotatedType) {
        return annotatedType.getAnnotations().stream().anyMatch(it -> it.annotationType() == Path.class)
                || annotatedType.getMethods().stream().anyMatch(this::isJaxRs);
    }

    private <T> boolean isJaxRs(final AnnotatedMethod<? super T> m) {
        return m.getAnnotations().stream().anyMatch(it -> it.annotationType().isAnnotationPresent(HttpMethod.class));
    }
}
