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

package com.hypixel.hytale.server.core.util.concurrent;

import java.security.Permission;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
import javax.annotation.Nonnull;
import java.util.concurrent.Semaphore;

public class ThreadUtil
{
    public static void forceTimeHighResolution() {
        final Thread t = new Thread(() -> {
            try {
                while (!Thread.interrupted()) {
                    Thread.sleep(Long.MAX_VALUE);
                }
            }
            catch (final InterruptedException ignored) {
                Thread.currentThread().interrupt();
            }
            return;
        }, "ForceTimeHighResolution");
        t.setDaemon(true);
        t.start();
    }
    
    public static void createKeepAliveThread(@Nonnull final Semaphore alive) {
        final Thread t = new Thread(() -> {
            try {
                alive.acquire();
            }
            catch (final InterruptedException ignored) {
                Thread.currentThread().interrupt();
            }
            return;
        }, "KeepAlive");
        t.setDaemon(false);
        t.start();
    }
    
    @Nonnull
    public static ExecutorService newCachedThreadPool(final int maximumPoolSize, @Nonnull final ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(0, maximumPoolSize, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), threadFactory);
    }
    
    @Nonnull
    public static ThreadFactory daemon(@Nonnull final String name) {
        return r -> {
            final Thread t = new Thread(r, name);
            t.setDaemon(true);
            return t;
        };
    }
    
    @Nonnull
    public static ThreadFactory daemonCounted(@Nonnull final String name) {
        final AtomicLong count = new AtomicLong();
        return r -> {
            new Thread(r, String.format(name, count.incrementAndGet()));
            final Thread thread;
            final Thread t = thread;
            t.setDaemon(true);
            return t;
        };
    }
    
    static class ThreadWatcher extends SecurityManager
    {
        private final Predicate<Thread> predicate;
        private final Consumer<Thread> action;
        
        public ThreadWatcher(final Predicate<Thread> predicate, final Consumer<Thread> action) {
            this.predicate = predicate;
            this.action = action;
        }
        
        @Override
        public void checkPermission(final Permission perm) {
        }
        
        @Override
        public void checkPermission(final Permission perm, final Object context) {
        }
        
        @Override
        public void checkAccess(final ThreadGroup g) {
            final Thread creatingThread = Thread.currentThread();
            if (this.predicate.test(creatingThread)) {
                this.action.accept(creatingThread);
            }
        }
    }
}
