/*
 * 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.impl;

import static java.util.Collections.list;
import static java.util.Optional.ofNullable;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Event;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.MultivaluedMap;

import io.opentracing.Scope;
import io.opentracing.ScopeManager;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMap;

import org.apache.geronimo.microprofile.opentracing.config.GeronimoOpenTracingConfig;

@ApplicationScoped
public class GeronimoTracer implements Tracer {

    @Inject
    private ScopeManager scopeManager;

    @Inject
    private IdGenerator idGenerator;

    @Inject
    private Event<FinishedSpan> finishedSpanEvent;

    @Inject
    private GeronimoOpenTracingConfig config;

    private String spanIdHeader;
    private String traceIdHeader;
    private String baggageHeaderPrefix;

    @PostConstruct
    private void init() {
        spanIdHeader = config.read("propagation.headers.spanId", "X-B3-SpanId");
        traceIdHeader = config.read("propagation.headers.traceId", "X-B3-TraceId");
        baggageHeaderPrefix = config.read("propagation.headers.baggagePrefix", "baggage-");
    }

    @Override
    public ScopeManager scopeManager() {
        return scopeManager;
    }

    @Override
    public Span activeSpan() {
        return ofNullable(scopeManager.active()).map(Scope::span).orElse(null);
    }

    @Override
    public SpanBuilder buildSpan(final String operationName) {
        return new SpanBuilderImpl(
                this, (traceId, baggages) -> newContext(traceId, idGenerator.next(), baggages),
                span -> finishedSpanEvent.fire(new FinishedSpan(processNewSpan(span))), operationName, idGenerator);
    }

    @Override
    public <C> void inject(final SpanContext spanContext, final Format<C> format, final C carrier) {
        if (!TextMap.class.isInstance(carrier)) {
            throw new IllegalArgumentException("Only TextMap are supported");
        }
        final TextMap textMap = TextMap.class.cast(carrier);
        final SpanContextImpl context = SpanContextImpl.class.cast(spanContext);
        textMap.put(traceIdHeader, String.valueOf(context.getTraceId()));
        textMap.put(spanIdHeader, String.valueOf(context.getSpanId()));
        context.getBaggageItems().forEach((k, v) -> textMap.put(baggageHeaderPrefix + k, v));
    }

    @Override
    public <C> SpanContext extract(final Format<C> format, final C carrier) {
        if (JaxRsHeaderTextMap.class.isInstance(carrier)) {
            final MultivaluedMap<String, ?> map = JaxRsHeaderTextMap.class.cast(carrier).getMap();
            final String traceid = (String) map.getFirst(traceIdHeader);
            final String spanid = (String) map.getFirst(spanIdHeader);
            if (traceid != null && spanid != null) {
                return newContext(traceid, spanid, map.keySet().stream().filter(it -> it.startsWith(baggageHeaderPrefix))
                        .collect(toMap(identity(), k -> String.valueOf(map.getFirst(k)))));
            }
            return null;
        }
        if (ServletHeaderTextMap.class.isInstance(carrier)) {
            final HttpServletRequest req = ServletHeaderTextMap.class.cast(carrier).getRequest();
            final String traceid = req.getHeader(traceIdHeader);
            final String spanid = req.getHeader(spanIdHeader);
            if (traceid != null && spanid != null) {
                return newContext(traceid, spanid, list(req.getHeaderNames()).stream().filter(it -> it.startsWith(baggageHeaderPrefix))
                        .collect(toMap(identity(), k -> String.valueOf(req.getHeader(k)))));
            }
            return null;
        }
        if (!TextMap.class.isInstance(carrier)) {
            throw new IllegalArgumentException("Only TextMap are supported");
        }
        final Iterator<Map.Entry<String, String>> textMap = TextMap.class.cast(carrier).iterator();
        String traceId = null;
        String spanId = null;
        final Map<String, String> baggages = new HashMap<>();
        while (textMap.hasNext()) {
            final Map.Entry<String, String> next = textMap.next();
            if (next.getKey().startsWith(baggageHeaderPrefix)) {
                baggages.put(next.getKey(), next.getValue());
            } else if (spanIdHeader.equals(next.getKey())) {
                spanId = next.getValue();
            } else if (traceIdHeader.equals(next.getKey())) {
                traceId = next.getValue();
            }
        }
        if (traceId != null && spanId != null) {
            return newContext(traceId, spanId, baggages);
        }
        return null;
    }

    protected Span processNewSpan(final SpanImpl span) {
        return span;
    }

    protected SpanContextImpl newContext(final Object traceId, final Object spanId, final Map<String, String> baggages) {
        return new SpanContextImpl(traceId, spanId, baggages);
    }
}
