package com.codahale.dropwizard.config;

import com.codahale.metrics.MetricRegistry;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.codahale.dropwizard.Bundle;
import com.codahale.dropwizard.ConfiguredBundle;
import com.codahale.dropwizard.Service;
import com.codahale.dropwizard.cli.Command;
import com.codahale.dropwizard.cli.ConfiguredCommand;
import com.codahale.dropwizard.config.provider.ConfigurationSourceProvider;
import com.codahale.dropwizard.config.provider.FileConfigurationSourceProvider;
import com.codahale.dropwizard.json.ObjectMapperFactory;

import java.util.List;

public class Bootstrap<T extends Configuration> {
    private final Service<T> service;
    private ConfigurationSourceProvider configurationProvider = new FileConfigurationSourceProvider();
    private final ObjectMapperFactory objectMapperFactory;
    private final List<Bundle> bundles;
    private final List<ConfiguredBundle<? super T>> configuredBundles;
    private final List<Command> commands;
    private final MetricRegistry metricRegistry;

    public Bootstrap(Service<T> service) {
        this.service = service;
        this.objectMapperFactory = new ObjectMapperFactory();
        this.bundles = Lists.newArrayList();
        this.configuredBundles = Lists.newArrayList();
        this.commands = Lists.newArrayList();
        this.metricRegistry = new MetricRegistry();
    }

    public Service<T> getService() {
        return service;
    }

    public ConfigurationSourceProvider getConfigurationProvider() {
        return configurationProvider;
    }

    public void setConfigurationProvider(ConfigurationSourceProvider configurationProvider) {
        this.configurationProvider = configurationProvider;
    }

    public void addBundle(Bundle bundle) {
        bundle.initialize(this);
        bundles.add(bundle);
    }

    public void addBundle(ConfiguredBundle<? super T> bundle) {
        bundle.initialize(this);
        configuredBundles.add(bundle);
    }

    public void addCommand(Command command) {
        commands.add(command);
    }

    public void addCommand(ConfiguredCommand<T> command) {
        commands.add(command);
    }

    public ObjectMapperFactory getObjectMapperFactory() {
        return objectMapperFactory;
    }

    public void runWithBundles(T configuration, Environment environment) throws Exception {
        for (Bundle bundle : bundles) {
            bundle.run(environment);
        }
        for (ConfiguredBundle<? super T> bundle : configuredBundles) {
            bundle.run(configuration, environment);
        }
    }

    public ImmutableList<Command> getCommands() {
        return ImmutableList.copyOf(commands);
    }

    public MetricRegistry getMetricRegistry() {
        return metricRegistry;
    }
}

@@ -38,140 +38,8 @@
 g;%0A%0A
-import com.codahale.metrics.MetricRegistry;%0Aimport com.google.common.collect.ImmutableList;%0Aimport com.google.common.collect.Lists;%0A
 impo
@@ -473,16 +473,536 @@
 actory;%0A
+import com.codahale.metrics.Metric;%0Aimport com.codahale.metrics.MetricRegistry;%0Aimport com.codahale.metrics.MetricSet;%0Aimport com.codahale.metrics.jvm.BufferPoolMetricSet;%0Aimport com.codahale.metrics.jvm.GarbageCollectorMetricSet;%0Aimport com.codahale.metrics.jvm.MemoryUsageGaugeSet;%0Aimport com.codahale.metrics.jvm.ThreadStatesGaugeSet;%0Aimport com.google.common.collect.ImmutableList;%0Aimport com.google.common.collect.ImmutableMap;%0Aimport com.google.common.collect.Lists;%0A%0Aimport java.lang.management.ManagementFactory;
 %0Aimport 
@@ -1016,16 +1016,38 @@
 il.List;
+%0Aimport java.util.Map;
 %0A%0Apublic
@@ -1824,24 +1824,656 @@
 Registry();%0A
+        metricRegistry.registerAll(new MetricSet() %7B%0A            @Override%0A            public Map%3CString, Metric%3E getMetrics() %7B%0A                return ImmutableMap.%3CString, Metric%3Eof(%0A                        %22jvm.buffers%22,%0A                        new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()),%0A                        %22jvm.gc%22,%0A                        new GarbageCollectorMetricSet(),%0A                        %22jvm.memory%22,%0A                        new MemoryUsageGaugeSet(),%0A                        %22jvm.threads%22,%0A                        new ThreadStatesGaugeSet()%0A                );%0A            %7D%0A        %7D);%0A
     %7D%0A%0A    p

Add JVM instrumentation.