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

import static java.lang.Thread.NORM_PRIORITY;
import static java.util.Optional.ofNullable;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.eclipse.microprofile.metrics.MetricRegistry.Type.BASE;
import static org.eclipse.microprofile.metrics.MetricRegistry.Type.VENDOR;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.stream.Stream;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Destroyed;
import javax.enterprise.context.Initialized;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.servlet.ServletContext;

import org.apache.geronimo.microprofile.opentracing.common.impl.FinishedSpan;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.health.HealthCheckResponse;
import org.eclipse.microprofile.metrics.Metered;
import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.Snapshot;
import org.eclipse.microprofile.metrics.annotation.RegistryType;

import io.opentracing.Span;

// TODO: make span dependency optional and composable (events?)
@ApplicationScoped
public class MicroprofileDatabase {

    @Inject
    @ConfigProperty(name = "geronimo.microprofile.reporter.metrics.pollingInterval", defaultValue = "5000")
    private Long pollingInterval;

    @Inject
    @RegistryType(type = BASE)
    private MetricRegistry baseRegistry;

    @Inject
    @RegistryType(type = VENDOR)
    private MetricRegistry vendorRegistry;

    @Inject
    private MetricRegistry applicationRegistry;

    @Inject
    private HealthRegistry healthRegistry;

    private ScheduledExecutorService scheduler;

    private ScheduledFuture<?> pollFuture;

    private Map<String, MetricRegistry> metrics;

    private final InMemoryDatabase<Span> spanDatabase = new InMemoryDatabase<>("none");
    private final Map<String, InMemoryDatabase<Long>> counters = new HashMap<>();
    private final Map<String, InMemoryDatabase<Double>> gauges = new HashMap<>();
    private final Map<String, InMemoryDatabase<Snapshot>> histograms = new HashMap<>();
    private final Map<String, InMemoryDatabase<MeterSnapshot>> meters = new HashMap<>();
    private final Map<String, InMemoryDatabase<TimerSnapshot>> timers = new HashMap<>();
    private final Map<String, InMemoryDatabase<CheckSnapshot>> checks = new HashMap<>();

    public InMemoryDatabase<Span> getSpans() {
        return spanDatabase;
    }

    public Map<String, InMemoryDatabase<Long>> getCounters() {
        return counters;
    }

    public Map<String, InMemoryDatabase<Double>> getGauges() {
        return gauges;
    }

    public Map<String, InMemoryDatabase<Snapshot>> getHistograms() {
        return histograms;
    }

    public Map<String, InMemoryDatabase<MeterSnapshot>> getMeters() {
        return meters;
    }

    public Map<String, InMemoryDatabase<TimerSnapshot>> getTimers() {
        return timers;
    }

    public Map<String, InMemoryDatabase<CheckSnapshot>> getChecks() {
        return checks;
    }

    private void poll() {
        metrics.forEach(this::updateMetrics);

        healthRegistry.doCheck().forEach(this::updateHealthCheck);
    }

    private void updateHealthCheck(final HealthCheckResponse healthCheckResponse) {
        final String name = healthCheckResponse.getName();
        InMemoryDatabase<CheckSnapshot> db = checks.get(name);
        if (db == null) {
            db = new InMemoryDatabase<>("check");
            final InMemoryDatabase<CheckSnapshot> existing = checks.putIfAbsent(name, db);
            if (existing != null) {
                db = existing;
            }
        }
        db.add(new CheckSnapshot(
                healthCheckResponse.getName(),
                ofNullable(healthCheckResponse.getState()).orElse(HealthCheckResponse.State.DOWN).name(),
                healthCheckResponse.getData().map(HashMap::new).orElseGet(HashMap::new)));
    }

    private void updateMetrics(final String type, final MetricRegistry registry) {
        registry.getCounters().forEach((name, counter) -> {
            final String virtualName = getMetricStorageName(type, name);
            final long count = counter.getCount();
            getDb(counters, virtualName, registry, name).add(count);
        });

        registry.getGauges().forEach((name, gauge) -> {
            final String virtualName = getMetricStorageName(type, name);
            final Object value = gauge.getValue();
            if (Number.class.isInstance(value)) {
                try {
                    getDb(gauges, virtualName, registry, name).add(Number.class.cast(value).doubleValue());
                } catch (final NullPointerException | NumberFormatException nfe) {
                    // ignore, we can't do much if the value is not a double
                }
            } // else ignore, will not be able to do anything of it anyway
        });

        registry.getHistograms().forEach((name, histogram) -> {
            final String virtualName = getMetricStorageName(type, name);
            final Snapshot snapshot = histogram.getSnapshot();
            getDb(histograms, virtualName, registry, name).add(snapshot);
        });

        registry.getMeters().forEach((name, meter) -> {
            final String virtualName = getMetricStorageName(type, name);
            final MeterSnapshot snapshot = new MeterSnapshot(meter);
            getDb(meters, virtualName, registry, name).add(snapshot);
        });

        registry.getTimers().forEach((name, timer) -> {
            final String virtualName = getMetricStorageName(type, name);
            final TimerSnapshot snapshot = new TimerSnapshot(new MeterSnapshot(timer), timer.getSnapshot());
            getDb(timers, virtualName, registry, name).add(snapshot);
        });
    }

    // alternatively we can decorate the registries and register/unregister following the registry lifecycle
    // shouldnt be worth it for now
    private <T> InMemoryDatabase<T> getDb(final Map<String, InMemoryDatabase<T>> registry,
                                          final String virtualName, final MetricRegistry source,
                                          final String key) {
        InMemoryDatabase<T> db = registry.get(virtualName);
        if (db == null) {
            db = new InMemoryDatabase<>(ofNullable(source.getMetadata().get(key).getUnit()).orElse(""));
            final InMemoryDatabase<T> existing = registry.putIfAbsent(virtualName, db);
            if (existing != null) {
                db = existing;
            }
        }
        return db;
    }

    private String getMetricStorageName(final String type, final String name) {
        return type + "#" + name;
    }

    private String name(final Object start) {
        if (ServletContext.class.isInstance(start)) {
            final ServletContext context = ServletContext.class.cast(start);
            try {
                return "[web=" + context.getVirtualServerName() + '/' + context.getContextPath() + "]";
            } catch (final Error | Exception e) { // no getVirtualServerName() for this context
                return "[web=" + context.getContextPath() + "]";
            }
        }
        return start.toString();
    }

    void onSpan(@Observes final FinishedSpan span) {
        final Span value = span.getSpan();
        if (value.getClass().getName().equals("org.apache.geronimo.microprofile.opentracing.common.impl.SpanImpl")) {
            spanDatabase.add(value);
        } // else we will not be able to read the metadata
    }

    void onStart(@Observes @Initialized(ApplicationScoped.class) final Object start) {
        metrics = new HashMap<>(3);
        metrics.put("vendor", vendorRegistry);
        metrics.put("base", baseRegistry);
        metrics.put("application", applicationRegistry);

        final ClassLoader appLoader = Thread.currentThread().getContextClassLoader();
        scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
            final Thread thread = new Thread(r, "geronimo-microprofile-reporter-poller-" + name(start));
            thread.setContextClassLoader(appLoader);
            if (thread.isDaemon()) {
                thread.setDaemon(false);
            }
            if (thread.getPriority() != NORM_PRIORITY) {
                thread.setPriority(NORM_PRIORITY);
            }
            return thread;
        });
        pollFuture = scheduler.scheduleAtFixedRate(this::poll, pollingInterval, pollingInterval, MILLISECONDS);
    }

    void onStop(@Observes @Destroyed(ApplicationScoped.class) final Object stop) {
        if (pollFuture != null) {
            pollFuture.cancel(true);
            pollFuture = null;
        }
        if (scheduler != null) {
            scheduler.shutdownNow();
            try {
                scheduler.awaitTermination(10, SECONDS);
            } catch (final InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            scheduler = null;
        }
        Stream.of(counters, gauges, histograms, meters, timers).forEach(Map::clear);
    }

    public static class TimerSnapshot {
        private final MeterSnapshot meter;
        private final Snapshot histogram;

        private TimerSnapshot(final MeterSnapshot meter, final Snapshot histogram) {
            this.meter = meter;
            this.histogram = histogram;
        }
    }

    public static class MeterSnapshot {
        private final long count;
        private final double rateMean;
        private final double rate1;
        private final double rate5;
        private final double rate15;

        private MeterSnapshot(final Metered meter) {
            this(meter.getCount(), meter.getMeanRate(), meter.getOneMinuteRate(), meter.getFiveMinuteRate(), meter.getFifteenMinuteRate());
        }

        private MeterSnapshot(final long count, final double rateMean,
                              final double rate1, final double rate5, final double rate15) {
            this.count = count;
            this.rateMean = rateMean;
            this.rate1 = rate1;
            this.rate5 = rate5;
            this.rate15 = rate15;
        }
    }

    public static class CheckSnapshot {
        private final String name;
        private final String state;
        private final Map<String, Object> data;

        private CheckSnapshot(final String name, final String state, final Map<String, Object> data) {
            this.name = name;
            this.state = state;
            this.data = data;
        }
    }
}
