/*
 * 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.common.microprofile.server;

import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;

import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import javax.ws.rs.HttpMethod;
import javax.ws.rs.Path;
import javax.ws.rs.container.DynamicFeature;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.Provider;

import org.apache.geronimo.microprofile.opentracing.common.config.GeronimoOpenTracingConfig;
import org.apache.geronimo.microprofile.opentracing.common.spi.Container;
import org.eclipse.microprofile.opentracing.Traced;

import io.opentracing.Tracer;

@Provider
// @Dependent
public class GeronimoOpenTracingFeature implements DynamicFeature {
    private Tracer tracer;
    private GeronimoOpenTracingConfig config;
    private Container container;
    private Collection<Pattern> skipPatterns;
    private String globalFilterRequestSkip;
    private boolean globalIgnoreMetadataResources;

    public void setTracer(final Tracer tracer) {
        this.tracer = tracer;
    }

    public void setConfig(final GeronimoOpenTracingConfig config) {
        this.config = config;
        this.globalFilterRequestSkip = config.read("server.filter.request.skip", "false");
        this.globalIgnoreMetadataResources = Boolean.parseBoolean(config.read("server.filter.request.ignoreMetadaResources", "true"));
    }

    public void setContainer(final Container container) {
        this.container = container;
    }

    @Override
    public void configure(final ResourceInfo resourceInfo, final FeatureContext context) {
        if ((tracer == null || config == null) && container == null) {
            container = Container.get();
        }
        if (tracer == null) { // configured instead of scanned
            tracer = container.lookup(Tracer.class);
        }
        if (config == null) {
            config = container.lookup(GeronimoOpenTracingConfig.class);
        }
        if (skipPatterns == null) {
            skipPatterns = ofNullable(config.read("mp.opentracing.server.skip-pattern", null))
                .map(it -> Stream.of(it.split("\\|")).map(String::trim).filter(p -> !p.isEmpty()).map(Pattern::compile).collect(toList()))
                .orElseGet(Collections::emptyList);
        }

        final Optional<Traced> traced = ofNullable(ofNullable(resourceInfo.getResourceMethod().getAnnotation(Traced.class))
                .orElseGet(() -> resourceInfo.getResourceClass().getAnnotation(Traced.class)));
        if (!traced.map(Traced::value).orElse(true)) {
            return;
        }
        final String path = Stream.of(
                ofNullable(resourceInfo.getResourceClass().getAnnotation(Path.class)).map(Path::value).orElse(""),
                ofNullable(resourceInfo.getResourceMethod().getAnnotation(Path.class)).map(Path::value).orElse(""))
                .map(it -> it.substring(it.startsWith("/") ? 1 : 0, it.endsWith("/") ? it.length() - 1 : it.length()))
                .filter(it -> !it.isEmpty())
                .collect(joining("/", "/", ""));
        if (skipPatterns.stream().anyMatch(it -> it.matcher(path).matches())) {
            return;
        }

        final String operationName = traced.map(Traced::operationName).filter(v -> !v.trim().isEmpty()).orElseGet(() -> {
            if (Boolean.parseBoolean(config.read("server.filter.request.operationName.usePath", "false"))) {
                return getHttpMethod(resourceInfo) + ':' + getMethodPath(resourceInfo);
            } else if ("http-path".equals(config.read("mp.opentracing.server.operation-name-provider", null))) {
                return getMethodPath(resourceInfo);
            }
            return buildDefaultName(resourceInfo);
        });
        context.register(new OpenTracingServerResponseFilter())
                .register(new OpenTracingServerRequestFilter(operationName, tracer,
                        shouldSkip(resourceInfo),
                        Boolean.parseBoolean(config.read("server.filter.request.skipDefaultTags", "false"))));
    }

    private boolean shouldSkip(final ResourceInfo resourceInfo) {
        if (Boolean.parseBoolean(config.read(
                "server.filter.request.skip." + resourceInfo.getResourceClass().getName() + "_" + resourceInfo.getResourceMethod().getName(),
                config.read("server.filter.request.skip." + resourceInfo.getResourceClass().getName(),
                        globalFilterRequestSkip)))) {
            return true;
        }
        return globalIgnoreMetadataResources && isMetadataResource(resourceInfo.getResourceClass().getName());
    }

    private boolean isMetadataResource(final String name) {
        return name.startsWith("org.apache.geronimo.microprofile.openapi.jaxrs.") ||
                name.startsWith("org.apache.geronimo.microprofile.metrics.jaxrs.") ||
                name.startsWith("org.apache.geronimo.microprofile.impl.health.jaxrs.") ||
                name.startsWith("org.apache.geronimo.microprofile.reporter.storage.front.") ||
                name.startsWith("org.microprofileext.openapi.swaggerui.");
    }

    private String getMethodPath(final ResourceInfo resourceInfo) {
        final String classPath = ofNullable(resourceInfo.getResourceClass().getAnnotation(Path.class))
                .map(Path::value).orElse("");
        final String methodPath = ofNullable(resourceInfo.getResourceMethod().getAnnotation(Path.class))
                .map(Path::value).orElse("");
        return Stream.of(classPath, methodPath)
                     .map(it -> it.substring(it.startsWith("/") ? 1 : 0, it.length() - (it.endsWith("/") ? 1 : 0)))
                     .filter(it -> !it.isEmpty())
                     .collect(joining("/", "/", ""));
    }

    private String buildDefaultName(final ResourceInfo resourceInfo) {
        return getHttpMethod(resourceInfo) + ':' + resourceInfo.getResourceClass().getName() + "."
                + resourceInfo.getResourceMethod().getName();
    }

    private String getHttpMethod(final ResourceInfo resourceInfo) {
        return Stream.of(resourceInfo.getResourceMethod().getAnnotations())
                .filter(a -> a.annotationType().isAnnotationPresent(HttpMethod.class)).findFirst()
                .map(a -> a.annotationType().getAnnotation(HttpMethod.class).value()).orElse("");
    }
}
