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

package org.jline.terminal.impl.jna.linux;

import com.sun.jna.LastErrorException;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import org.jline.terminal.impl.AbstractPty;
import org.jline.terminal.Size;
import org.jline.terminal.Attributes;
import java.io.IOException;
import java.io.FileDescriptor;
import org.jline.terminal.spi.SystemStream;
import org.jline.terminal.spi.TerminalProvider;
import org.jline.terminal.impl.jna.JnaNativePty;

public class LinuxNativePty extends JnaNativePty
{
    private static final CLibrary C_LIBRARY;
    
    public static LinuxNativePty current(final TerminalProvider provider, final SystemStream systemStream) throws IOException {
        switch (systemStream) {
            case Output: {
                return new LinuxNativePty(provider, systemStream, -1, null, 0, FileDescriptor.in, 1, FileDescriptor.out, ttyname(0));
            }
            case Error: {
                return new LinuxNativePty(provider, systemStream, -1, null, 0, FileDescriptor.in, 2, FileDescriptor.err, ttyname(0));
            }
            default: {
                throw new IllegalArgumentException("Unsupported stream for console: " + systemStream);
            }
        }
    }
    
    public static LinuxNativePty open(final TerminalProvider provider, final Attributes attr, final Size size) throws IOException {
        final int[] master = { 0 };
        final int[] slave = { 0 };
        final byte[] buf = new byte[64];
        UtilLibrary.INSTANCE.openpty(master, slave, buf, (attr != null) ? new CLibrary.termios(attr) : null, (size != null) ? new CLibrary.winsize(size) : null);
        int len;
        for (len = 0; buf[len] != 0; ++len) {}
        final String name = new String(buf, 0, len);
        return new LinuxNativePty(provider, null, master[0], AbstractPty.newDescriptor(master[0]), slave[0], AbstractPty.newDescriptor(slave[0]), name);
    }
    
    public LinuxNativePty(final TerminalProvider provider, final SystemStream systemStream, final int master, final FileDescriptor masterFD, final int slave, final FileDescriptor slaveFD, final String name) {
        super(provider, systemStream, master, masterFD, slave, slaveFD, name);
    }
    
    public LinuxNativePty(final TerminalProvider provider, final SystemStream systemStream, final int master, final FileDescriptor masterFD, final int slave, final FileDescriptor slaveFD, final int slaveOut, final FileDescriptor slaveOutFD, final String name) {
        super(provider, systemStream, master, masterFD, slave, slaveFD, slaveOut, slaveOutFD, name);
    }
    
    @Override
    public Attributes getAttr() throws IOException {
        final CLibrary.termios termios = new CLibrary.termios();
        LinuxNativePty.C_LIBRARY.tcgetattr(this.getSlave(), termios);
        return termios.toAttributes();
    }
    
    @Override
    protected void doSetAttr(final Attributes attr) throws IOException {
        final CLibrary.termios termios = new CLibrary.termios(attr);
        final CLibrary.termios org = new CLibrary.termios();
        LinuxNativePty.C_LIBRARY.tcgetattr(this.getSlave(), org);
        org.c_iflag = termios.c_iflag;
        org.c_oflag = termios.c_oflag;
        org.c_lflag = termios.c_lflag;
        System.arraycopy(termios.c_cc, 0, org.c_cc, 0, termios.c_cc.length);
        LinuxNativePty.C_LIBRARY.tcsetattr(this.getSlave(), 1, org);
    }
    
    @Override
    public Size getSize() throws IOException {
        final CLibrary.winsize sz = new CLibrary.winsize();
        LinuxNativePty.C_LIBRARY.ioctl(this.getSlave(), CLibrary.TIOCGWINSZ, sz);
        return sz.toSize();
    }
    
    @Override
    public void setSize(final Size size) throws IOException {
        final CLibrary.winsize sz = new CLibrary.winsize(size);
        LinuxNativePty.C_LIBRARY.ioctl(this.getSlave(), CLibrary.TIOCSWINSZ, sz);
    }
    
    public static int isatty(final int fd) {
        return LinuxNativePty.C_LIBRARY.isatty(fd);
    }
    
    public static String ttyname(final int slave) {
        final byte[] buf = new byte[64];
        LinuxNativePty.C_LIBRARY.ttyname_r(slave, buf, buf.length);
        int len;
        for (len = 0; buf[len] != 0; ++len) {}
        return new String(buf, 0, len);
    }
    
    static {
        C_LIBRARY = (CLibrary)Native.load(Platform.C_LIBRARY_NAME, (Class)CLibrary.class);
    }
    
    public interface UtilLibrary extends Library
    {
        public static final UtilLibrary INSTANCE = (UtilLibrary)Native.load("util", (Class)UtilLibrary.class);
        
        void openpty(final int[] p0, final int[] p1, final byte[] p2, final CLibrary.termios p3, final CLibrary.winsize p4) throws LastErrorException;
    }
}
