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

package org.jline.terminal.impl.jni;

import org.jline.terminal.impl.PosixPtyTerminal;
import java.io.OutputStream;
import java.io.InputStream;
import org.jline.terminal.impl.PosixSysTerminal;
import org.jline.terminal.impl.jni.win.NativeWinSysTerminal;
import org.jline.utils.OSUtils;
import org.jline.terminal.Terminal;
import java.nio.charset.Charset;
import org.jline.terminal.Size;
import org.jline.terminal.Attributes;
import java.io.IOException;
import org.jline.terminal.impl.jni.freebsd.FreeBsdNativePty;
import org.jline.terminal.impl.jni.solaris.SolarisNativePty;
import org.jline.terminal.impl.jni.osx.OsXNativePty;
import org.jline.terminal.impl.jni.linux.LinuxNativePty;
import org.jline.terminal.spi.Pty;
import org.jline.terminal.spi.SystemStream;
import org.jline.utils.Log;
import org.jline.nativ.JLineNativeLoader;
import org.jline.terminal.spi.TerminalProvider;

public class JniTerminalProvider implements TerminalProvider
{
    public JniTerminalProvider() {
        try {
            JLineNativeLoader.initialize();
        }
        catch (final Exception e) {
            Log.debug("Failed to load JLine native library: " + e.getMessage(), e);
        }
    }
    
    @Override
    public String name() {
        return "jni";
    }
    
    public Pty current(final SystemStream systemStream) throws IOException {
        final String osName = System.getProperty("os.name");
        if (osName.startsWith("Linux")) {
            return LinuxNativePty.current(this, systemStream);
        }
        if (osName.startsWith("Mac") || osName.startsWith("Darwin")) {
            return OsXNativePty.current(this, systemStream);
        }
        if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) {
            return SolarisNativePty.current(this, systemStream);
        }
        if (osName.startsWith("FreeBSD")) {
            return FreeBsdNativePty.current(this, systemStream);
        }
        throw new UnsupportedOperationException();
    }
    
    public Pty open(final Attributes attributes, final Size size) throws IOException {
        final String osName = System.getProperty("os.name");
        if (osName.startsWith("Linux")) {
            return LinuxNativePty.open(this, attributes, size);
        }
        if (osName.startsWith("Mac") || osName.startsWith("Darwin")) {
            return OsXNativePty.open(this, attributes, size);
        }
        if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) {
            return SolarisNativePty.open(this, attributes, size);
        }
        if (osName.startsWith("FreeBSD")) {
            return FreeBsdNativePty.open(this, attributes, size);
        }
        throw new UnsupportedOperationException();
    }
    
    @Override
    public Terminal sysTerminal(final String name, final String type, final boolean ansiPassThrough, final Charset encoding, final Charset inputEncoding, final Charset outputEncoding, final boolean nativeSignals, final Terminal.SignalHandler signalHandler, final boolean paused, final SystemStream systemStream) throws IOException {
        if (OSUtils.IS_WINDOWS) {
            return this.winSysTerminal(name, type, ansiPassThrough, encoding, inputEncoding, outputEncoding, outputEncoding, nativeSignals, signalHandler, paused, systemStream);
        }
        return this.posixSysTerminal(name, type, ansiPassThrough, encoding, inputEncoding, outputEncoding, outputEncoding, nativeSignals, signalHandler, paused, systemStream);
    }
    
    @Deprecated
    @Override
    public Terminal sysTerminal(final String name, final String type, final boolean ansiPassThrough, final Charset encoding, final Charset stdinEncoding, final Charset stdoutEncoding, final Charset stderrEncoding, final boolean nativeSignals, final Terminal.SignalHandler signalHandler, final boolean paused, final SystemStream systemStream) throws IOException {
        if (OSUtils.IS_WINDOWS) {
            return this.winSysTerminal(name, type, ansiPassThrough, encoding, stdinEncoding, stdoutEncoding, stderrEncoding, nativeSignals, signalHandler, paused, systemStream);
        }
        return this.posixSysTerminal(name, type, ansiPassThrough, encoding, stdinEncoding, stdoutEncoding, stderrEncoding, nativeSignals, signalHandler, paused, systemStream);
    }
    
    public Terminal winSysTerminal(final String name, final String type, final boolean ansiPassThrough, final Charset encoding, final boolean nativeSignals, final Terminal.SignalHandler signalHandler, final boolean paused, final SystemStream systemStream) throws IOException {
        return this.winSysTerminal(name, type, ansiPassThrough, encoding, encoding, encoding, encoding, nativeSignals, signalHandler, paused, systemStream);
    }
    
    public Terminal winSysTerminal(final String name, final String type, final boolean ansiPassThrough, final Charset encoding, final Charset stdinEncoding, final Charset stdoutEncoding, final Charset stderrEncoding, final boolean nativeSignals, final Terminal.SignalHandler signalHandler, final boolean paused, final SystemStream systemStream) throws IOException {
        return NativeWinSysTerminal.createTerminal(this, systemStream, name, type, ansiPassThrough, encoding, stdinEncoding, stdoutEncoding, stderrEncoding, nativeSignals, signalHandler, paused);
    }
    
    public Terminal posixSysTerminal(final String name, final String type, final boolean ansiPassThrough, final Charset encoding, final boolean nativeSignals, final Terminal.SignalHandler signalHandler, final boolean paused, final SystemStream systemStream) throws IOException {
        return this.posixSysTerminal(name, type, ansiPassThrough, encoding, encoding, encoding, encoding, nativeSignals, signalHandler, paused, systemStream);
    }
    
    public Terminal posixSysTerminal(final String name, final String type, final boolean ansiPassThrough, final Charset encoding, final Charset stdinEncoding, final Charset stdoutEncoding, final Charset stderrEncoding, final boolean nativeSignals, final Terminal.SignalHandler signalHandler, final boolean paused, final SystemStream systemStream) throws IOException {
        final Pty pty = this.current(systemStream);
        final Charset outputEncoding = (systemStream == SystemStream.Error) ? stderrEncoding : stdoutEncoding;
        return new PosixSysTerminal(name, type, pty, encoding, stdinEncoding, outputEncoding, nativeSignals, signalHandler);
    }
    
    @Override
    public Terminal newTerminal(final String name, final String type, final InputStream in, final OutputStream out, final Charset encoding, final Charset inputEncoding, final Charset outputEncoding, final Terminal.SignalHandler signalHandler, final boolean paused, final Attributes attributes, final Size size) throws IOException {
        final Pty pty = this.open(attributes, size);
        return new PosixPtyTerminal(name, type, pty, in, out, encoding, inputEncoding, outputEncoding, signalHandler, paused);
    }
    
    @Deprecated
    @Override
    public Terminal newTerminal(final String name, final String type, final InputStream in, final OutputStream out, final Charset encoding, final Charset stdinEncoding, final Charset stdoutEncoding, final Charset stderrEncoding, final Terminal.SignalHandler signalHandler, final boolean paused, final Attributes attributes, final Size size) throws IOException {
        final Pty pty = this.open(attributes, size);
        return new PosixPtyTerminal(name, type, pty, in, out, encoding, stdinEncoding, stdoutEncoding, signalHandler, paused);
    }
    
    @Override
    public boolean isSystemStream(final SystemStream stream) {
        try {
            if (OSUtils.IS_WINDOWS) {
                return this.isWindowsSystemStream(stream);
            }
            return this.isPosixSystemStream(stream);
        }
        catch (final Throwable t) {
            Log.debug("Exception while checking system stream (this may disable the JNI provider)", t);
            return false;
        }
    }
    
    public boolean isWindowsSystemStream(final SystemStream stream) {
        return NativeWinSysTerminal.isWindowsSystemStream(stream);
    }
    
    public boolean isPosixSystemStream(final SystemStream stream) {
        return JniNativePty.isPosixSystemStream(stream);
    }
    
    @Override
    public String systemStreamName(final SystemStream stream) {
        return JniNativePty.posixSystemStreamName(stream);
    }
    
    @Override
    public int systemStreamWidth(final SystemStream stream) {
        return JniNativePty.systemStreamWidth(stream);
    }
    
    @Override
    public String toString() {
        return "TerminalProvider[" + this.name() + "]";
    }
}
