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

package org.jline.jansi;

import org.jline.utils.OSUtils;
import java.io.UnsupportedEncodingException;
import java.io.OutputStream;
import org.jline.jansi.io.AnsiProcessor;
import org.jline.jansi.io.AnsiOutputStream;
import org.jline.terminal.spi.TerminalExt;
import org.jline.terminal.impl.DumbTerminal;
import java.util.Objects;
import java.io.IOException;
import java.io.IOError;
import org.jline.terminal.TerminalBuilder;
import org.jline.terminal.Terminal;
import java.io.PrintStream;

public class AnsiConsole
{
    public static final String JANSI_MODE = "jansi.mode";
    public static final String JANSI_OUT_MODE = "jansi.out.mode";
    public static final String JANSI_ERR_MODE = "jansi.err.mode";
    public static final String JANSI_MODE_STRIP = "strip";
    public static final String JANSI_MODE_FORCE = "force";
    public static final String JANSI_MODE_DEFAULT = "default";
    public static final String JANSI_COLORS = "jansi.colors";
    public static final String JANSI_OUT_COLORS = "jansi.out.colors";
    public static final String JANSI_ERR_COLORS = "jansi.err.colors";
    public static final String JANSI_COLORS_16 = "16";
    public static final String JANSI_COLORS_256 = "256";
    public static final String JANSI_COLORS_TRUECOLOR = "truecolor";
    public static final String JANSI_NORESET = "jansi.noreset";
    public static final String JANSI_GRACEFUL = "jansi.graceful";
    public static final String JANSI_PROVIDERS = "jansi.providers";
    public static final String JANSI_PROVIDER_JNI = "jni";
    public static final String JANSI_PROVIDER_FFM = "ffm";
    public static final String JANSI_PROVIDER_NATIVE_IMAGE = "native-image";
    private static final PrintStream system_out;
    private static PrintStream out;
    private static final PrintStream system_err;
    private static PrintStream err;
    static final boolean IS_WINDOWS;
    static final boolean IS_CYGWIN;
    static final boolean IS_MSYSTEM;
    static final boolean IS_CONEMU;
    static final int ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4;
    static int STDOUT_FILENO;
    static int STDERR_FILENO;
    private static int installed;
    static Terminal terminal;
    
    public static int getTerminalWidth() {
        int w = out().getTerminalWidth();
        if (w <= 0) {
            w = err().getTerminalWidth();
        }
        return w;
    }
    
    private AnsiConsole() {
    }
    
    public static Terminal getTerminal() {
        return AnsiConsole.terminal;
    }
    
    public static void setTerminal(final Terminal terminal) {
        AnsiConsole.terminal = terminal;
    }
    
    static synchronized void doInstall() {
        try {
            if (AnsiConsole.terminal == null) {
                final TerminalBuilder builder = TerminalBuilder.builder().system(true).name("jansi").providers(System.getProperty("jansi.providers"));
                final String graceful = System.getProperty("jansi.graceful");
                if (graceful != null) {
                    builder.dumb(Boolean.parseBoolean(graceful));
                }
                AnsiConsole.terminal = builder.build();
            }
            if (AnsiConsole.out == null) {
                AnsiConsole.out = ansiStream(true);
                AnsiConsole.err = ansiStream(false);
            }
        }
        catch (final IOException e) {
            throw new IOError(e);
        }
    }
    
    static synchronized void doUninstall() {
        try {
            if (AnsiConsole.terminal != null) {
                AnsiConsole.terminal.close();
            }
        }
        catch (final IOException e) {
            throw new IOError(e);
        }
        finally {
            AnsiConsole.terminal = null;
            AnsiConsole.out = null;
            AnsiConsole.err = null;
        }
    }
    
    private static AnsiPrintStream ansiStream(final boolean stdout) throws IOException {
        final AnsiProcessor processor = null;
        final AnsiOutputStream.IoRunnable installer = null;
        final AnsiOutputStream.IoRunnable uninstaller = null;
        final OutputStream out = AnsiConsole.terminal.output();
        final Terminal terminal = AnsiConsole.terminal;
        Objects.requireNonNull(terminal);
        final AnsiOutputStream.WidthSupplier width = terminal::getWidth;
        final AnsiType type = (AnsiConsole.terminal instanceof DumbTerminal) ? AnsiType.Unsupported : ((((TerminalExt)AnsiConsole.terminal).getSystemStream() != null) ? AnsiType.Native : AnsiType.Redirected);
        final String jansiMode = System.getProperty(stdout ? "jansi.out.mode" : "jansi.err.mode", System.getProperty("jansi.mode"));
        AnsiMode mode;
        if ("force".equals(jansiMode)) {
            mode = AnsiMode.Force;
        }
        else if ("strip".equals(jansiMode)) {
            mode = AnsiMode.Strip;
        }
        else {
            mode = ((type == AnsiType.Native) ? AnsiMode.Default : AnsiMode.Strip);
        }
        final String jansiColors = System.getProperty(stdout ? "jansi.out.colors" : "jansi.err.colors", System.getProperty("jansi.colors"));
        AnsiColors colors;
        if ("truecolor".equals(jansiColors)) {
            colors = AnsiColors.TrueColor;
        }
        else if ("256".equals(jansiColors)) {
            colors = AnsiColors.Colors256;
        }
        else if (jansiColors != null) {
            colors = AnsiColors.Colors16;
        }
        else {
            final String colorterm;
            if ((colorterm = System.getenv("COLORTERM")) != null && (colorterm.contains("truecolor") || colorterm.contains("24bit"))) {
                colors = AnsiColors.TrueColor;
            }
            else {
                final String term;
                if ((term = System.getenv("TERM")) != null && term.contains("-direct")) {
                    colors = AnsiColors.TrueColor;
                }
                else if (term != null && term.contains("-256color")) {
                    colors = AnsiColors.Colors256;
                }
                else {
                    colors = AnsiColors.Colors16;
                }
            }
        }
        final boolean resetAtUninstall = type != AnsiType.Unsupported && !getBoolean("jansi.noreset");
        return newPrintStream(new AnsiOutputStream(out, width, mode, processor, type, colors, AnsiConsole.terminal.encoding(), installer, uninstaller, resetAtUninstall), AnsiConsole.terminal.encoding().name());
    }
    
    private static AnsiPrintStream newPrintStream(final AnsiOutputStream out, final String enc) {
        if (enc != null) {
            try {
                return new AnsiPrintStream(out, true, enc);
            }
            catch (final UnsupportedEncodingException ex) {}
        }
        return new AnsiPrintStream(out, true);
    }
    
    static boolean getBoolean(final String name) {
        boolean result = false;
        try {
            final String val = System.getProperty(name);
            result = (val.isEmpty() || Boolean.parseBoolean(val));
        }
        catch (final IllegalArgumentException | NullPointerException ex) {}
        return result;
    }
    
    public static AnsiPrintStream out() {
        doInstall();
        return (AnsiPrintStream)AnsiConsole.out;
    }
    
    public static PrintStream sysOut() {
        return AnsiConsole.system_out;
    }
    
    public static AnsiPrintStream err() {
        doInstall();
        return (AnsiPrintStream)AnsiConsole.err;
    }
    
    public static PrintStream sysErr() {
        return AnsiConsole.system_err;
    }
    
    public static synchronized void systemInstall() {
        if (AnsiConsole.installed == 0) {
            doInstall();
            System.setOut(AnsiConsole.out);
            System.setErr(AnsiConsole.err);
        }
        ++AnsiConsole.installed;
    }
    
    public static synchronized boolean isInstalled() {
        return AnsiConsole.installed > 0;
    }
    
    public static synchronized void systemUninstall() {
        --AnsiConsole.installed;
        if (AnsiConsole.installed == 0) {
            doUninstall();
            System.setOut(AnsiConsole.system_out);
            System.setErr(AnsiConsole.system_err);
        }
    }
    
    static {
        system_out = System.out;
        system_err = System.err;
        IS_WINDOWS = OSUtils.IS_WINDOWS;
        IS_CYGWIN = (AnsiConsole.IS_WINDOWS && System.getenv("PWD") != null && System.getenv("PWD").startsWith("/"));
        IS_MSYSTEM = (AnsiConsole.IS_WINDOWS && System.getenv("MSYSTEM") != null && (System.getenv("MSYSTEM").startsWith("MINGW") || System.getenv("MSYSTEM").equals("MSYS")));
        IS_CONEMU = (AnsiConsole.IS_WINDOWS && System.getenv("ConEmuPID") != null);
        AnsiConsole.STDOUT_FILENO = 1;
        AnsiConsole.STDERR_FILENO = 2;
    }
}
