/*
 * 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.sling.commons.metrics.internal;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.management.MBeanServer;

import com.codahale.metrics.JmxReporter;
import com.codahale.metrics.MetricRegistry;
import org.apache.sling.commons.metrics.Meter;
import org.apache.sling.commons.metrics.MetricsService;
import org.apache.sling.commons.metrics.Timer;
import org.apache.sling.commons.metrics.Counter;
import org.apache.sling.commons.metrics.Histogram;
import org.apache.sling.commons.metrics.Metric;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;

@Component(service = {}, immediate = true)
public class MetricsServiceImpl implements MetricsService {
    private final List<ServiceRegistration> regs = new ArrayList<>();
    private final ConcurrentMap<String, Metric> metrics = new ConcurrentHashMap<>();
    private final MetricRegistry registry = new MetricRegistry();
    private final BundleMetricsMapper metricsMapper = new BundleMetricsMapper(registry);
    private GaugeManager gaugeManager;

    @Reference(cardinality = ReferenceCardinality.OPTIONAL)
    private MBeanServer server;

    private JmxReporter reporter;

    /*  WARNING: if any OSGi configuration parameters are added to this class
     *  we’ll need to handle the service restart case to prevent service
     *  references retrieved using MetricsServiceFactory from becoming
     *  stale. See discussion in SLING-6702.
     */
    @Activate
    private void activate(BundleContext context, Map<String, Object> config) {
        enableJMXReporter();

        gaugeManager = new GaugeManager(context, registry, metricsMapper);

        final Dictionary<String, String> svcProps = new Hashtable<>();
        svcProps.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Metrics Service");
        svcProps.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
        regs.add(context.registerService(MetricsService.class.getName(),
                new InternalMetricsServiceFactory(this, metricsMapper), svcProps));

        final Dictionary<String, String> regProps = new Hashtable<>();
        regProps.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Metrics Registry");
        regProps.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
        regProps.put("name", "sling");
        regs.add(context.registerService(MetricRegistry.class.getName(), registry, regProps));
    }

    @Deactivate
    private void deactivate() throws IOException {
        for (ServiceRegistration reg : regs) {
            reg.unregister();
        }
        regs.clear();

        gaugeManager.close();

        metrics.clear();

        if (reporter != null) {
            reporter.close();
        }
    }

    @Override
    public Timer timer(String name) {
        return getOrAdd(name, MetricBuilder.TIMERS);
    }

    @Override
    public Histogram histogram(String name) {
        return getOrAdd(name, MetricBuilder.HISTOGRAMS);
    }

    @Override
    public Counter counter(String name) {
        return getOrAdd(name, MetricBuilder.COUNTERS);
    }

    @Override
    public Meter meter(String name) {
        return getOrAdd(name, MetricBuilder.METERS);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <A> A adaptTo(Class<A> type) {
        if (type == MetricRegistry.class){
            return (A) registry;
        }
        return null;
    }

    MetricRegistry getRegistry() {
        return registry;
    }

    @SuppressWarnings("unchecked")
    private <T extends Metric> T getOrAdd(String name, MetricBuilder<T> builder) {
        final Metric metric = metrics.get(name);
        if (builder.isInstance(metric)) {
            return (T) metric;
        } else if (metric == null) {
            try {
                return register(name, builder.newMetric(registry, name));
            } catch (IllegalArgumentException e) {
                final Metric added = metrics.get(name);
                if (builder.isInstance(added)) {
                    return (T) added;
                }
            }
        }
        throw new IllegalArgumentException(name + " is already used for a different type of metric");
    }

    private <T extends Metric> T register(String name, T metric) throws IllegalArgumentException {
        final Metric existing = metrics.putIfAbsent(name, metric);
        if (existing != null) {
            throw new IllegalArgumentException("A metric named " + name + " already exists");
        }
        return metric;
    }

    /**
     * A quick and easy way of capturing the notion of default metrics.
     */
    private interface MetricBuilder<T extends Metric> {
        MetricBuilder<Counter> COUNTERS = new MetricBuilder<Counter>() {
            @Override
            public Counter newMetric(MetricRegistry registry, String name) {
                return new CounterImpl(registry.counter(name));
            }

            @Override
            public boolean isInstance(Metric metric) {
                return Counter.class.isInstance(metric);
            }
        };

        MetricBuilder<Histogram> HISTOGRAMS = new MetricBuilder<Histogram>() {
            @Override
            public Histogram newMetric(MetricRegistry registry, String name) {
                return new HistogramImpl(registry.histogram(name));
            }

            @Override
            public boolean isInstance(Metric metric) {
                return Histogram.class.isInstance(metric);
            }
        };

        MetricBuilder<Meter> METERS = new MetricBuilder<Meter>() {
            @Override
            public Meter newMetric(MetricRegistry registry, String name) {
                return new MeterImpl(registry.meter(name));
            }

            @Override
            public boolean isInstance(Metric metric) {
                return Meter.class.isInstance(metric);
            }
        };

        MetricBuilder<Timer> TIMERS = new MetricBuilder<Timer>() {
            @Override
            public Timer newMetric(MetricRegistry registry, String name) {
                return new TimerImpl(registry.timer(name));
            }

            @Override
            public boolean isInstance(Metric metric) {
                return Timer.class.isInstance(metric);
            }
        };

        T newMetric(MetricRegistry registry, String name);

        boolean isInstance(Metric metric);
    }

    private void enableJMXReporter() {
        if (server == null){
            server = ManagementFactory.getPlatformMBeanServer();
        }

        reporter = JmxReporter.forRegistry(registry)
                .inDomain(BundleMetricsMapper.DEFAULT_DOMAIN_NAME)
                .createsObjectNamesWith(metricsMapper)
                .registerWith(server)
                .build();
        reporter.start();
    }
}
