package com.airlock.iam.common.infrastructure;

import com.airlock.iam.common.infrastructure.jackson.JacksonConfigurator;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.google.common.base.Stopwatch;
import java.util.concurrent.TimeUnit;
import org.glassfish.jersey.server.ResourceConfig;

public class RestConfigurator {
   private static final ELogger LOG = ELoggerFactory.getLogger(RestConfigurator.class);
   private final RestApplicationConfig restConfig;
   private final ResourceConfig configurableApplication;

   public RestConfigurator(ResourceConfig configurableApplication, RestApplicationConfig restConfig) {
      this.configurableApplication = configurableApplication;
      this.restConfig = restConfig;
   }

   public void configure() {
      Stopwatch stopwatch = Stopwatch.createUnstarted();
      stopwatch.reset().start();
      this.configurableApplication
         .setApplicationName(this.restConfig.applicationName())
         .registerClasses(this.restConfig.applicationComponentProvider().jaxRsComponents().toArray(Class[]::new));
      LOG.debug("JAX-RS: " + stopwatch.elapsed(TimeUnit.MILLISECONDS) + " ms");
      stopwatch.reset().start();
      HK2Configurator.HK2Binders binders = new HK2Configurator().registerHk2Binders(this.configurableApplication);
      LOG.debug("HK2: " + stopwatch.elapsed(TimeUnit.MILLISECONDS) + " ms");
      stopwatch.reset().start();
      GuiceConfigurator guiceConfigurator = new GuiceConfigurator(this.restConfig);
      guiceConfigurator.registerGuice(this.configurableApplication, binders);
      LOG.debug("Guice: " + stopwatch.elapsed(TimeUnit.MILLISECONDS) + " ms");
      stopwatch.reset().start();
      new OrikaMapperConfigurator().registerOrikaMappings(this.configurableApplication, this.restConfig);
      LOG.debug("Orika: " + stopwatch.elapsed(TimeUnit.MILLISECONDS) + " ms");
      stopwatch.reset().start();
      new JacksonConfigurator().configureJackson(this.configurableApplication, binders);
      LOG.debug("Jackson: " + stopwatch.elapsed(TimeUnit.MILLISECONDS) + " ms");
   }
}
