// 
// Decompiled by Procyon v0.6.0
// 

package org.jline.utils;

import java.util.ArrayList;
import java.util.Objects;
import java.util.List;

public final class ShutdownHooks
{
    private static final List<Task> tasks;
    private static Thread hook;
    
    public static synchronized <T extends Task> T add(final T task) {
        Objects.requireNonNull(task);
        if (ShutdownHooks.hook == null) {
            ShutdownHooks.hook = addHook(new Thread("JLine Shutdown Hook") {
                @Override
                public void run() {
                    runTasks();
                }
            });
        }
        Log.debug("Adding shutdown-hook task: ", task);
        ShutdownHooks.tasks.add(task);
        return task;
    }
    
    private static synchronized void runTasks() {
        Log.debug("Running all shutdown-hook tasks");
        for (final Task task : ShutdownHooks.tasks.toArray(new Task[ShutdownHooks.tasks.size()])) {
            Log.debug("Running task: ", task);
            try {
                task.run();
            }
            catch (final Throwable e) {
                Log.warn("Task failed", e);
            }
        }
        ShutdownHooks.tasks.clear();
    }
    
    private static Thread addHook(final Thread thread) {
        Log.debug("Registering shutdown-hook: ", thread);
        Runtime.getRuntime().addShutdownHook(thread);
        return thread;
    }
    
    public static synchronized void remove(final Task task) {
        Objects.requireNonNull(task);
        if (ShutdownHooks.hook == null) {
            return;
        }
        ShutdownHooks.tasks.remove(task);
        if (ShutdownHooks.tasks.isEmpty()) {
            removeHook(ShutdownHooks.hook);
            ShutdownHooks.hook = null;
        }
    }
    
    private static void removeHook(final Thread thread) {
        Log.debug("Removing shutdown-hook: ", thread);
        try {
            Runtime.getRuntime().removeShutdownHook(thread);
        }
        catch (final IllegalStateException ex) {}
    }
    
    static {
        tasks = new ArrayList<Task>();
    }
    
    public interface Task
    {
        void run() throws Exception;
    }
}
