package io.liveoak.container.extension.service;

import com.fasterxml.jackson.databind.node.ObjectNode;
import io.liveoak.common.util.ConversionUtils;
import io.liveoak.container.extension.ServiceUpdateResponder;
import io.liveoak.spi.Application;
import io.liveoak.spi.RequestContext;
import io.liveoak.spi.resource.RootResource;
import io.liveoak.spi.resource.async.Resource;
import org.jboss.msc.inject.Injector;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
import org.jboss.msc.value.InjectedValue;

import java.util.function.Consumer;

/**
 * @author Bob McWhirter
 * @author Ken Finnigan
 */
public class InitializeResourceService implements Service<Void> {

    public InitializeResourceService() {
    }

    public InitializeResourceService(Consumer<Exception> exceptionConsumer) {
        this.exceptionConsumer = exceptionConsumer;
    }

    @Override
    public void start(StartContext context) throws StartException {
        RequestContext reqContext = new RequestContext.Builder().application(applicationInjector.getOptionalValue());
        context.asynchronous();
        try {
            this.resourceInjector.getValue().initializeProperties(reqContext, ConversionUtils.convert(this.configurationInjector.getValue()), new ServiceUpdateResponder(context));
        } catch (Exception e) {
            if (this.exceptionConsumer != null) {
                this.exceptionConsumer.accept(e);
                context.complete();
            } else {
                throw new StartException(e);
            }
        }
    }

    @Override
    public void stop(StopContext context) {

    }

    @Override
    public Void getValue() throws IllegalStateException, IllegalArgumentException {
        return null;
    }

    public Injector<ObjectNode> configurationInjector() {
        return this.configurationInjector;
    }

    public Injector<RootResource> resourceInjector() {
        return this.resourceInjector;
    }

    public Injector<Application> applicationInjector() {
        return this.applicationInjector;
    }

    private InjectedValue<ObjectNode> configurationInjector = new InjectedValue<>();
    private InjectedValue<RootResource> resourceInjector = new InjectedValue<>();
    private InjectedValue<Application> applicationInjector = new InjectedValue<>();
    private Consumer<Exception> exceptionConsumer;

}

@@ -328,55 +328,8 @@
 ce;%0A
-import io.liveoak.spi.resource.async.Resource;%0A
 impo
@@ -362,16 +362,16 @@
 jector;%0A
+
 import o
@@ -771,24 +771,52 @@
 Service() %7B%0A
+        this.async = false;%0A
     %7D%0A%0A    p
@@ -940,16 +940,43 @@
 nsumer;%0A
+        this.async = true;%0A
     %7D%0A%0A 
@@ -1170,24 +1170,25 @@
 alValue());%0A
+%0A
         cont
@@ -1207,24 +1207,129 @@
 nous();%0A
+%0A        if (async) %7B%0A            try %7B%0A                new Thread(() -%3E %7B%0A                    try %7B%0A    
         
 try %7B%0A  
@@ -1312,38 +1312,32 @@
 y %7B%0A            
-try %7B%0A
             this
@@ -1500,16 +1500,28 @@
 text));%0A
+            
         
@@ -1552,24 +1552,36 @@
             
+       
+     
 if (this.exc
@@ -1614,32 +1614,44 @@
                 
+          
+  
 this.exceptionCo
@@ -1676,32 +1676,44 @@
                 
+            
 context.complete
@@ -1728,16 +1728,28 @@
         
+ 
+           
 %7D else %7B
@@ -1769,36 +1769,814 @@
     
-throw new StartException(e);
+            context.failed(new StartException(e));%0A                        %7D%0A                    %7D%0A                %7D, %22InitializeResourceService starter - %22 + this.resourceInjector.getValue().id()).start();%0A            %7D catch (Throwable t) %7B%0A                context.failed(new StartException(t));%0A            %7D%0A        %7D else %7B%0A            try %7B%0A                this.resourceInjector.getValue().initializeProperties(reqContext, ConversionUtils.convert(this.configurationInjector.getValue()), new ServiceUpdateResponder(context));%0A            %7D catch (Exception e) %7B%0A                if (this.exceptionConsumer != null) %7B%0A                    this.exceptionConsumer.accept(e);%0A                    context.complete();%0A                %7D else %7B%0A                    throw new StartException(e);%0A                %7D
 %0A   
@@ -3351,32 +3351,32 @@
 ectedValue%3C%3E();%0A
-
     private Cons
@@ -3409,12 +3409,39 @@
 onsumer;
+%0A    private boolean async;
 %0A%0A%7D%0A

Modify InitializeResourceService to support async invocation for ApplicationContext usage