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

package org.jline.terminal.impl.jna;

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import org.jline.terminal.Size;
import org.jline.terminal.Attributes;
import java.io.IOException;
import org.jline.terminal.impl.jna.freebsd.FreeBsdNativePty;
import org.jline.terminal.impl.jna.solaris.SolarisNativePty;
import org.jline.terminal.impl.jna.linux.LinuxNativePty;
import org.jline.terminal.impl.jna.osx.OsXNativePty;
import com.sun.jna.Platform;
import org.jline.terminal.spi.SystemStream;
import org.jline.terminal.spi.TerminalProvider;
import java.io.FileDescriptor;
import org.jline.terminal.spi.Pty;
import org.jline.terminal.impl.AbstractPty;

public abstract class JnaNativePty extends AbstractPty implements Pty
{
    private final int master;
    private final int slave;
    private final int slaveOut;
    private final String name;
    private final FileDescriptor masterFD;
    private final FileDescriptor slaveFD;
    private final FileDescriptor slaveOutFD;
    
    public static JnaNativePty current(final TerminalProvider provider, final SystemStream systemStream) throws IOException {
        if (Platform.isMac()) {
            if (Platform.is64Bit() && Platform.isARM()) {
                throw new UnsupportedOperationException();
            }
            return OsXNativePty.current(provider, systemStream);
        }
        else {
            if (Platform.isLinux()) {
                return LinuxNativePty.current(provider, systemStream);
            }
            if (Platform.isSolaris()) {
                return SolarisNativePty.current(provider, systemStream);
            }
            if (Platform.isFreeBSD()) {
                return FreeBsdNativePty.current(provider, systemStream);
            }
            throw new UnsupportedOperationException();
        }
    }
    
    public static JnaNativePty open(final TerminalProvider provider, final Attributes attr, final Size size) throws IOException {
        if (Platform.isMac()) {
            if (Platform.is64Bit() && Platform.isARM()) {
                throw new UnsupportedOperationException();
            }
            return OsXNativePty.open(provider, attr, size);
        }
        else {
            if (Platform.isLinux()) {
                return LinuxNativePty.open(provider, attr, size);
            }
            if (Platform.isSolaris()) {
                return SolarisNativePty.open(provider, attr, size);
            }
            if (Platform.isFreeBSD()) {
                return FreeBsdNativePty.open(provider, attr, size);
            }
            throw new UnsupportedOperationException();
        }
    }
    
    protected JnaNativePty(final TerminalProvider provider, final SystemStream systemStream, final int master, final FileDescriptor masterFD, final int slave, final FileDescriptor slaveFD, final String name) {
        this(provider, systemStream, master, masterFD, slave, slaveFD, slave, slaveFD, name);
    }
    
    protected JnaNativePty(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);
        this.master = master;
        this.slave = slave;
        this.slaveOut = slaveOut;
        this.name = name;
        this.masterFD = masterFD;
        this.slaveFD = slaveFD;
        this.slaveOutFD = slaveOutFD;
    }
    
    @Override
    public void close() throws IOException {
        if (this.master > 0) {
            this.getMasterInput().close();
        }
        if (this.slave > 0) {
            this.getSlaveInput().close();
        }
    }
    
    public int getMaster() {
        return this.master;
    }
    
    public int getSlave() {
        return this.slave;
    }
    
    public int getSlaveOut() {
        return this.slaveOut;
    }
    
    public String getName() {
        return this.name;
    }
    
    public FileDescriptor getMasterFD() {
        return this.masterFD;
    }
    
    public FileDescriptor getSlaveFD() {
        return this.slaveFD;
    }
    
    public FileDescriptor getSlaveOutFD() {
        return this.slaveOutFD;
    }
    
    @Override
    public InputStream getMasterInput() {
        return new FileInputStream(this.getMasterFD());
    }
    
    @Override
    public OutputStream getMasterOutput() {
        return new FileOutputStream(this.getMasterFD());
    }
    
    @Override
    protected InputStream doGetSlaveInput() {
        return new FileInputStream(this.getSlaveFD());
    }
    
    @Override
    public OutputStream getSlaveOutput() {
        return new FileOutputStream(this.getSlaveOutFD());
    }
    
    @Override
    public String toString() {
        return "JnaNativePty[" + this.getName() + "]";
    }
    
    public static boolean isPosixSystemStream(final SystemStream stream) {
        switch (stream) {
            case Input: {
                return isatty(0);
            }
            case Output: {
                return isatty(1);
            }
            case Error: {
                return isatty(2);
            }
            default: {
                return false;
            }
        }
    }
    
    public static String posixSystemStreamName(final SystemStream stream) {
        switch (stream) {
            case Input: {
                return ttyname(0);
            }
            case Output: {
                return ttyname(1);
            }
            case Error: {
                return ttyname(2);
            }
            default: {
                return null;
            }
        }
    }
    
    private static boolean isatty(final int fd) {
        if (Platform.isMac()) {
            if (Platform.is64Bit() && Platform.isARM()) {
                throw new UnsupportedOperationException("Unsupported platform mac-aarch64");
            }
            return OsXNativePty.isatty(fd) == 1;
        }
        else {
            if (Platform.isLinux()) {
                return LinuxNativePty.isatty(fd) == 1;
            }
            if (Platform.isSolaris()) {
                return SolarisNativePty.isatty(fd) == 1;
            }
            return Platform.isFreeBSD() && FreeBsdNativePty.isatty(fd) == 1;
        }
    }
    
    private static String ttyname(final int fd) {
        if (Platform.isMac()) {
            if (Platform.is64Bit() && Platform.isARM()) {
                throw new UnsupportedOperationException("Unsupported platform mac-aarch64");
            }
            return OsXNativePty.ttyname(fd);
        }
        else {
            if (Platform.isLinux()) {
                return LinuxNativePty.ttyname(fd);
            }
            if (Platform.isSolaris()) {
                return SolarisNativePty.ttyname(fd);
            }
            if (Platform.isFreeBSD()) {
                return FreeBsdNativePty.ttyname(fd);
            }
            return null;
        }
    }
}
