package apoc;

import apoc.schema.AssertSchemaProcedure;
import apoc.trigger.Trigger;
import apoc.ttl.TTLLifeCycle;
import org.neo4j.kernel.extension.KernelExtensionFactory;
import org.neo4j.kernel.impl.logging.LogService;
import org.neo4j.kernel.impl.proc.Procedures;
import org.neo4j.kernel.impl.spi.KernelContext;
import org.neo4j.kernel.impl.util.JobScheduler;
import org.neo4j.kernel.internal.GraphDatabaseAPI;
import org.neo4j.kernel.lifecycle.Lifecycle;
import org.neo4j.kernel.lifecycle.LifecycleAdapter;
import org.neo4j.logging.Log;

/**
 * @author mh
 * @since 14.05.16
 */
public class ApocKernelExtensionFactory extends KernelExtensionFactory<ApocKernelExtensionFactory.Dependencies>{

    public ApocKernelExtensionFactory() {
        super("APOC");
    }

    public interface Dependencies {
        GraphDatabaseAPI graphdatabaseAPI();
        JobScheduler scheduler();
        Procedures procedures();
        LogService log();
    }

    @Override
    public Lifecycle newInstance(KernelContext context, Dependencies dependencies) throws Throwable {
        GraphDatabaseAPI db = dependencies.graphdatabaseAPI();
        LogService log = dependencies.log();
        return new LifecycleAdapter() {

            private Trigger.LifeCycle triggerLifeCycle;
            private Log userLog = log.getUserLog(ApocKernelExtensionFactory.class);
            private TTLLifeCycle ttlLifeCycle;

            @Override
            public void start() throws Throwable {
                ApocConfiguration.initialize(db);
                Pools.NEO4J_SCHEDULER = dependencies.scheduler();

                dependencies.procedures().register(new AssertSchemaProcedure(db, log.getUserLog(AssertSchemaProcedure.class)));
                ttlLifeCycle = new TTLLifeCycle(Pools.NEO4J_SCHEDULER, db, log.getUserLog(TTLLifeCycle.class));
                ttlLifeCycle.start();
                triggerLifeCycle = new Trigger.LifeCycle(db, log.getUserLog(Trigger.class));
                triggerLifeCycle.start();
            }

            @Override
            public void stop() throws Throwable {
                if (ttlLifeCycle !=null)
                    try {
                        ttlLifeCycle.stop();
                    } catch(Exception e) {
                        userLog.warn("Error stopping ttl service",e);
                    }
                if (triggerLifeCycle !=null)
                    try {
                        triggerLifeCycle.stop();
                    } catch(Exception e) {
                        userLog.warn("Error stopping trigger service",e);
                    }
            }
        };
    }

}

@@ -1587,17 +1587,16 @@
 uler();%0A
-%0A
         
@@ -1607,100 +1607,22 @@
     
-dependencies.procedures().register(new AssertSchemaProcedure(db, log.getUserLog(AssertSchema
+registerCustom
 Proc
@@ -1630,19 +1630,14 @@
 dure
-.class))
+s(
 );%0A
+%0A
     
@@ -1774,32 +1774,33 @@
 eCycle.start();%0A
+%0A
                 
@@ -1929,24 +1929,431 @@
          %7D%0A%0A
+            public void registerCustomProcedures() %7B%0A                try %7B%0A                    dependencies.procedures().register(new AssertSchemaProcedure(db, log.getUserLog(AssertSchemaProcedure.class)));%0A                %7D catch(Exception%7CError e) %7B%0A                    log.getUserLog(ArithmeticException.class).error(%22Cannot register procedure AssertSchemaProcedure%22,e);%0A                %7D%0A            %7D%0A%0A
             

Make apoc work with Neo4j 3.1.2 which removed an Kernal-API class