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

package com.hypixel.hytale.server.core.console;

import java.io.IOError;
import org.jline.reader.EndOfFileException;
import org.jline.reader.UserInterruptException;
import com.hypixel.hytale.server.core.ShutdownReason;
import com.hypixel.hytale.server.core.HytaleServer;
import com.hypixel.hytale.server.core.command.system.CommandSender;
import com.hypixel.hytale.server.core.command.system.CommandManager;
import org.jline.reader.LineReader;
import java.io.IOException;
import com.hypixel.hytale.logger.HytaleLogger;
import java.util.logging.Level;
import org.jline.reader.LineReaderBuilder;
import com.hypixel.hytale.logger.backend.HytaleConsole;
import com.hypixel.hytale.server.core.Constants;
import org.jline.terminal.TerminalBuilder;
import com.hypixel.hytale.server.core.command.system.AbstractCommand;
import com.hypixel.hytale.server.core.console.command.SayCommand;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import org.jline.terminal.Terminal;
import com.hypixel.hytale.common.plugin.PluginManifest;
import com.hypixel.hytale.server.core.plugin.JavaPlugin;

public class ConsoleModule extends JavaPlugin
{
    public static final PluginManifest MANIFEST;
    private static ConsoleModule instance;
    private Terminal terminal;
    private ConsoleRunnable consoleRunnable;
    
    public static ConsoleModule get() {
        return ConsoleModule.instance;
    }
    
    public ConsoleModule(@Nonnull final JavaPluginInit init) {
        super(init);
    }
    
    @Override
    protected void setup() {
        ConsoleModule.instance = this;
        this.getCommandRegistry().registerCommand(new SayCommand());
        try {
            final TerminalBuilder builder = TerminalBuilder.builder();
            if (Constants.SINGLEPLAYER) {
                builder.dumb(true);
            }
            else {
                builder.color(true);
            }
            this.terminal = builder.build();
            HytaleConsole.INSTANCE.setTerminal(this.terminal.getType());
            final LineReader lineReader = LineReaderBuilder.builder().terminal(this.terminal).build();
            this.consoleRunnable = new ConsoleRunnable(lineReader, ConsoleSender.INSTANCE);
            this.getLogger().at(Level.INFO).log("Setup console with type: %s", this.terminal.getType());
        }
        catch (final IOException e) {
            this.getLogger().at(Level.SEVERE).withCause(e).log("Failed to start console reader");
        }
    }
    
    @Override
    protected void shutdown() {
        this.getLogger().at(Level.INFO).log("Restoring terminal...");
        try {
            this.terminal.close();
        }
        catch (final IOException e) {
            HytaleLogger.getLogger().at(Level.SEVERE).withCause(e).log("Failed to restore terminal!");
        }
        this.consoleRunnable.interrupt();
    }
    
    public Terminal getTerminal() {
        return this.terminal;
    }
    
    static {
        MANIFEST = PluginManifest.corePlugin(ConsoleModule.class).build();
    }
    
    private static class ConsoleRunnable implements Runnable
    {
        private final LineReader lineReader;
        private final ConsoleSender consoleSender;
        @Nonnull
        private final Thread consoleThread;
        
        public ConsoleRunnable(final LineReader lineReader, final ConsoleSender consoleSender) {
            this.lineReader = lineReader;
            this.consoleSender = consoleSender;
            (this.consoleThread = new Thread(this, "ConsoleThread")).setDaemon(true);
            this.consoleThread.start();
        }
        
        @Override
        public void run() {
            try {
                final String terminalType = this.lineReader.getTerminal().getType();
                final boolean isDumb = "dumb".equals(terminalType) || "dumb-color".equals(terminalType);
                while (!this.consoleThread.isInterrupted()) {
                    String command = this.lineReader.readLine(isDumb ? null : "> ");
                    if (command == null) {
                        break;
                    }
                    command = command.trim();
                    if (!command.isEmpty() && command.charAt(0) == '/') {
                        command = command.substring(1);
                    }
                    CommandManager.get().handleCommand(this.consoleSender, command);
                }
            }
            catch (final UserInterruptException e) {
                HytaleServer.get().shutdownServer(ShutdownReason.SIGINT);
            }
            catch (final EndOfFileException | IOError endOfFileException | IOError) {}
        }
        
        public void interrupt() {
            this.consoleThread.interrupt();
        }
    }
}
