package net.serverpeon.sponge.akka.ext;

import akka.dispatch.DispatcherPrerequisites;
import akka.dispatch.ExecutorServiceConfigurator;
import akka.dispatch.ExecutorServiceFactory;
import com.google.common.base.Supplier;
import com.typesafe.config.Config;
import org.spongepowered.api.Game;
import org.spongepowered.api.service.scheduler.SynchronousScheduler;
import org.spongepowered.api.service.scheduler.Task;

import java.util.List;
import java.util.concurrent.*;

class ExecutorConfigurator extends ExecutorServiceConfigurator {
    private final ExecutorService executor;

    public ExecutorConfigurator(Object plugin, Game game, Config config,
                                DispatcherPrerequisites prereq) {
        super(config, prereq);
        this.executor = new SpongeExecutorService(
                game.getSyncScheduler(),
                plugin
        );
    }

    @Override
    public ExecutorServiceFactory createExecutorServiceFactory(String id, ThreadFactory threadFactory) {
        return new ExecutorFactory(this.executor);
    }

    private static class ExecutorFactory implements ExecutorServiceFactory {
        private final ExecutorService executor;

        public ExecutorFactory(ExecutorService executor) {
            this.executor = executor;
        }

        @Override
        public ExecutorService createExecutorService() {
            return this.executor;
        }
    }

    private static class SpongeExecutorService extends AbstractExecutorService {
        private final SynchronousScheduler scheduler;
        private final Object plugin;

        public SpongeExecutorService(SynchronousScheduler scheduler, Object plugin) {
            this.scheduler = scheduler;
            this.plugin = plugin;
        }

        @Override
        public void shutdown() {
            throw new UnsupportedOperationException("Unable to terminate delegate executor");
        }

        @Override
        public List<Runnable> shutdownNow() {
            throw new UnsupportedOperationException("Unable to terminate delegate executor");
        }

        @Override
        public boolean isShutdown() {
            return false;
        }

        @Override
        public boolean isTerminated() {
            return false;
        }

        @Override
        public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
            throw new UnsupportedOperationException("Unable to terminate delegate executor");
        }

        @Override
        public void execute(Runnable command) {
            scheduler.runTask(
                    plugin,
                    command
            ).or(TaskRejecter.INSTANCE);
        }
    }

    private static class TaskRejecter implements Supplier<Task> {
        public static final TaskRejecter INSTANCE = new TaskRejecter();

        @Override
        public Task get() {
            throw new RejectedExecutionException();
        }
    }
}

@@ -179,48 +179,8 @@
 ry;%0A
-import com.google.common.base.Supplier;%0A
 impo
@@ -297,104 +297,188 @@
 er.S
-ynchronousScheduler;%0Aimport org.spongepowered.api.service.scheduler.Task;%0A%0Aimport java.util.List
+chedulerService;%0A%0Aimport java.util.List;%0Aimport java.util.concurrent.AbstractExecutorService;%0Aimport java.util.concurrent.ExecutorService;%0Aimport java.util.concurrent.ThreadFactory
 ;%0Aim
@@ -507,9 +507,16 @@
 ent.
-*
+TimeUnit
 ;%0A%0Ac
@@ -874,12 +874,8 @@
 getS
-yncS
 ched
@@ -1563,27 +1563,16 @@
 e final 
-Synchronous
 Schedule
@@ -1564,32 +1564,39 @@
  final Scheduler
+Service
  scheduler;%0A    
@@ -1627,16 +1627,55 @@
  plugin;
+%0A        private final String taskName;
 %0A%0A      
@@ -1709,19 +1709,8 @@
 ice(
-Synchronous
 Sche
@@ -1714,16 +1714,23 @@
 cheduler
+Service
  schedul
@@ -1816,32 +1816,116 @@
 lugin = plugin;%0A
+            this.taskName = %22SpongeAkka-Task-%22 + plugin.getClass().getSimpleName();%0A
         %7D%0A%0A     
@@ -2732,16 +2732,21 @@
         
+this.
 schedule
@@ -2751,44 +2751,24 @@
 ler.
-run
+get
 Task
-(%0A                    plugin,
+Builder()
 %0A   
@@ -2784,23 +2784,33 @@
         
+.execute(
 command
+)
 %0A       
@@ -2818,288 +2818,76 @@
     
-).or(TaskRejecter.INSTANCE);%0A        %7D%0A    %7D%0A%0A    private static class TaskRejecter implements Supplier%3CTask%3E %7B%0A        public static final TaskRejecter INSTANCE = new TaskRejecter();%0A%0A        @Override%0A        public Task get() %7B%0A            throw new RejectedExecutionException(
+        .name(this.taskName)%0A                    .submit(this.plugin
 );%0A 

Update to new Scheduler API (SpongeAPI 227cf04e4ac4f5393f5dd0687f713bc00683e317)