package io.liveoak.container.zero.service;

import java.io.File;
import java.util.concurrent.TimeUnit;

import io.liveoak.container.extension.MediaTypeMountService;
import io.liveoak.container.extension.MountService;
import io.liveoak.container.tenancy.InternalApplication;
import io.liveoak.container.tenancy.InternalApplicationRegistry;
import io.liveoak.container.tenancy.MountPointResource;
import io.liveoak.container.zero.SystemResource;
import io.liveoak.container.zero.extension.ZeroExtension;
import io.liveoak.spi.LiveOak;
import io.liveoak.spi.MediaType;
import io.liveoak.spi.resource.RootResource;
import org.jboss.msc.inject.Injector;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceTarget;
import org.jboss.msc.service.StabilityMonitor;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
import org.jboss.msc.service.ValueService;
import org.jboss.msc.value.ImmediateValue;
import org.jboss.msc.value.InjectedValue;
import org.vertx.java.core.Vertx;

import static io.liveoak.spi.LiveOak.APPLICATIONS_DIR;
import static io.liveoak.spi.LiveOak.APPLICATION_REGISTRY;
import static io.liveoak.spi.LiveOak.VERTX;

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

    @Override
    public void start(StartContext context) throws StartException {
        ServiceTarget target = context.getChildTarget();
        StabilityMonitor monitor = new StabilityMonitor();
        target.addMonitor(monitor);

        ServiceName systemName = LiveOak.resource(ZeroExtension.APPLICATION_ID, "system");
        target.addService(systemName, new ValueService<SystemResource>(new ImmediateValue<>(new SystemResource())))
                .install();

        MountService<RootResource> mount = new MountService<>();
        target.addService(systemName.append("mount"), mount)
                .addDependency(LiveOak.applicationContext(ZeroExtension.APPLICATION_ID), MountPointResource.class, mount.mountPointInjector())
                .addDependency(systemName, RootResource.class, mount.resourceInjector())
                .install();

        ServiceName applicationsName = LiveOak.resource(ZeroExtension.APPLICATION_ID, "applications");
        ApplicationsResourceService applicationsResource = new ApplicationsResourceService();
        target.addService(applicationsName, applicationsResource)
                .addDependency(APPLICATION_REGISTRY, InternalApplicationRegistry.class, applicationsResource.applicationRegistryInjector())
                .install();

        MediaTypeMountService<RootResource> mediaTypeMount = new MediaTypeMountService<>(null, MediaType.JSON, true);
        target.addService(LiveOak.defaultMount(applicationsName), mediaTypeMount)
                .addDependency(LiveOak.applicationContext(ZeroExtension.APPLICATION_ID), MountPointResource.class, mediaTypeMount.mountPointInjector())
                .addDependency(applicationsName, RootResource.class, mediaTypeMount.resourceInjector())
                .install();

        // Install Local Applications Resource
        ServiceName localApplicationsName = LiveOak.resource(ZeroExtension.APPLICATION_ID, "local-applications");
        LocalApplicationsResourceService localAppsResourceService = new LocalApplicationsResourceService();
        target.addService(localApplicationsName, localAppsResourceService)
                .addDependency(APPLICATION_REGISTRY, InternalApplicationRegistry.class, localAppsResourceService.applicationRegistryInjector())
                .addDependency(APPLICATIONS_DIR, File.class, localAppsResourceService.applicationDirectoryInjector())
                .addDependency(VERTX, Vertx.class, localAppsResourceService.vertxInjector())
                .install();

        MediaTypeMountService<RootResource> localAppMediaTypeMount = new MediaTypeMountService<>(null, MediaType.LOCAL_APP_JSON, false);
        target.addService(LiveOak.defaultMount(localApplicationsName), localAppMediaTypeMount)
                .addDependency(LiveOak.applicationContext(ZeroExtension.APPLICATION_ID), MountPointResource.class, localAppMediaTypeMount.mountPointInjector())
                .addDependency(localApplicationsName, RootResource.class, localAppMediaTypeMount.resourceInjector())
                .install();

        try {
            monitor.awaitStability(200, TimeUnit.MILLISECONDS, null);
        } catch (InterruptedException e) {
            throw new StartException(e);
        }
        target.removeMonitor(monitor);
    }

    @Override
    public void stop(StopContext context) {

    }

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

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

    private InjectedValue<InternalApplication> applicationInjector = new InjectedValue<>();
}

@@ -61,46 +61,8 @@
 ile;
-%0Aimport java.util.concurrent.TimeUnit;
 %0A%0Aim
@@ -732,55 +732,8 @@
 et;%0A
-import org.jboss.msc.service.StabilityMonitor;%0A
 impo
@@ -1373,32 +1373,32 @@
 tartException %7B%0A
+
         ServiceT
@@ -1441,103 +1441,8 @@
 t();
-%0A        StabilityMonitor monitor = new StabilityMonitor();%0A        target.addMonitor(monitor);
 %0A%0A  
@@ -4247,226 +4247,8 @@
 l();
-%0A%0A        try %7B%0A            monitor.awaitStability(200, TimeUnit.MILLISECONDS, null);%0A        %7D catch (InterruptedException e) %7B%0A            throw new StartException(e);%0A        %7D%0A        target.removeMonitor(monitor);
 %0A   

Remove stability monitor from ZeroResourcesService, as it didn't solve the problem