package com.netflix.governator.guice.jetty;

import java.util.Map;

import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.ServletException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Injector;
import com.google.inject.Scopes;
import com.sun.jersey.api.core.ResourceConfig;
import com.sun.jersey.guice.JerseyServletModule;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
import com.sun.jersey.spi.container.servlet.WebConfig;

/**
 * Enhancement to {@link GuiceContainer} by allowing Jersey to be configured via bindings instead of 
 * statically in a {@link JerseyServletModule}.  In addition all singleton resources will be 
 * instantiated eagerly.
 * 
 * ```java
 * bind(GuiceContainer.class).to(GovernatorServletContainer.class).asEagerSingleton();
 * ```
 * 
 * To set up a Jersey endpoint,
 * 
 * ```java
 * serve("/*").with(GuiceContainer.class);  
 * ```
 * 
 * To customize the configuration of the Jersey endpoint
 * 
 * ```java
 * @Provides
 * ResourceConfig getResourceConfig() {
 *     return new PackagesResourceConfig(ImmutableMap.<String, Object>builder()
 *             .put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.example.resources")
 *             .put(ResourceConfig.FEATURE_DISABLE_WADL, "false")   // Enable WADL
 *             .build());
 * }
 * ```
 */
@Singleton
public final class GovernatorServletContainer extends GuiceContainer {
    private static final long serialVersionUID = -1350697205980976818L;

    private static final Logger LOG = LoggerFactory.getLogger(GovernatorServletContainer.class);
    
    private final Injector injector;
    private ResourceConfig args;
    
    static class Arguments {
        @com.google.inject.Inject(optional=true)
        ResourceConfig config;
    }
    
    @Inject
    GovernatorServletContainer(Injector injector, Arguments args) {
        super(injector);
        
        this.injector = injector;
        this.args = args.config;
    }

    @Override
    protected ResourceConfig getDefaultResourceConfig(
            Map<String, Object> props,
            WebConfig webConfig) throws ServletException {
        
        if (args == null) {
            args = super.getDefaultResourceConfig(props, webConfig);
        }
        
        for (Class<?> resource : args.getRootResourceClasses()) {
            if (Scopes.isSingleton(injector.getBinding(resource))) {
                LOG.info("Creating resource '{}'.", resource.getName());
                injector.getInstance(resource);
            }
            else {
                LOG.info("Resource '{}' will be created on first request.  Mark as @Singleton to create eagerly.", resource.getName());
            }
        }
        return args;
    }
}

@@ -732,31 +732,39 @@
 rly.%0A * %0A * 
-%60%60%60java
+%3Cpre%3E%0A * %7B@code
 %0A * bind(Gui
@@ -838,27 +838,35 @@
 leton();%0A * 
-%60%60%60
+%7D%0A * %3C/pre%3E
 %0A * %0A * To s
@@ -892,28 +892,35 @@
 oint,%0A *
- %0A * %60%60%60java
+%0A * %3Cpre%3E%0A * %7B@code
 %0A * serv
@@ -958,17 +958,23 @@
 ss);
-  %0A * %60%60%60
+%0A * %7D%0A * %3C/pre%3E
 %0A * 
@@ -1037,20 +1037,27 @@
 t%0A *
- %0A * %60%60%60java
+%0A * %3Cpre%3E%0A * %7B@code
 %0A * 
@@ -1394,11 +1394,19 @@
 %0A * 
-%60%60%60
+%7D%0A * %3C/pre%3E
 %0A */

Clean GovernatorServletContainer javadocs.