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

package org.jline.terminal.impl;

import java.util.List;
import java.util.ArrayList;
import org.jline.utils.NonBlockingReader;
import org.jline.terminal.spi.SystemStream;
import org.jline.terminal.spi.TerminalProvider;
import org.jline.terminal.Cursor;
import java.util.function.IntConsumer;
import org.jline.terminal.Size;
import java.io.IOError;
import java.util.Objects;
import java.io.IOException;
import java.nio.charset.Charset;
import org.jline.terminal.Terminal;
import org.jline.terminal.Attributes;
import org.jline.terminal.spi.Pty;

public abstract class AbstractPosixTerminal extends AbstractTerminal
{
    protected final Pty pty;
    protected final Attributes originalAttributes;
    
    public AbstractPosixTerminal(final String name, final String type, final Pty pty) throws IOException {
        this(name, type, pty, null, Terminal.SignalHandler.SIG_DFL);
    }
    
    public AbstractPosixTerminal(final String name, final String type, final Pty pty, final Charset encoding, final Terminal.SignalHandler signalHandler) throws IOException {
        this(name, type, pty, encoding, encoding, encoding, signalHandler);
    }
    
    public AbstractPosixTerminal(final String name, final String type, final Pty pty, final Charset encoding, final Charset inputEncoding, final Charset outputEncoding, final Terminal.SignalHandler signalHandler) throws IOException {
        super(name, type, encoding, inputEncoding, outputEncoding, signalHandler);
        Objects.requireNonNull(pty);
        this.pty = pty;
        this.originalAttributes = this.pty.getAttr();
    }
    
    public Pty getPty() {
        return this.pty;
    }
    
    @Override
    public Attributes getAttributes() {
        try {
            return this.pty.getAttr();
        }
        catch (final IOException e) {
            throw new IOError(e);
        }
    }
    
    @Override
    public void setAttributes(final Attributes attr) {
        try {
            this.pty.setAttr(attr);
        }
        catch (final IOException e) {
            throw new IOError(e);
        }
    }
    
    @Override
    public Size getSize() {
        try {
            return this.pty.getSize();
        }
        catch (final IOException e) {
            throw new IOError(e);
        }
    }
    
    @Override
    public void setSize(final Size size) {
        try {
            this.pty.setSize(size);
        }
        catch (final IOException e) {
            throw new IOError(e);
        }
    }
    
    @Override
    protected void doClose() throws IOException {
        super.doClose();
        this.pty.setAttr(this.originalAttributes);
        this.pty.close();
    }
    
    @Override
    public Cursor getCursorPosition(final IntConsumer discarded) {
        return CursorSupport.getCursorPosition(this, discarded);
    }
    
    @Override
    public TerminalProvider getProvider() {
        return this.getPty().getProvider();
    }
    
    @Override
    public SystemStream getSystemStream() {
        return this.getPty().getSystemStream();
    }
    
    @Override
    public String toString() {
        return this.getKind() + "[name='" + this.name + '\'' + ", pty='" + this.pty + '\'' + ", type='" + this.type + '\'' + ", size='" + this.getSize() + '\'' + ']';
    }
    
    @Override
    public int getDefaultForegroundColor() {
        try {
            this.writer().write("\u001b]10;?\u001b\\");
            this.writer().flush();
            return this.parseColorResponse(this.reader(), 10);
        }
        catch (final IOException e) {
            return -1;
        }
    }
    
    @Override
    public int getDefaultBackgroundColor() {
        try {
            this.writer().write("\u001b]11;?\u001b\\");
            this.writer().flush();
            return this.parseColorResponse(this.reader(), 11);
        }
        catch (final IOException e) {
            return -1;
        }
    }
    
    private int parseColorResponse(final NonBlockingReader reader, final int colorType) throws IOException {
        if (reader.peek(50L) < 0) {
            return -1;
        }
        if (reader.read(10L) != 27 || reader.read(10L) != 93) {
            return -1;
        }
        final int tens = reader.read(10L);
        final int ones = reader.read(10L);
        if (tens != 49 || (ones != 48 && ones != 49)) {
            return -1;
        }
        final int type = ones - 48 + 10;
        if (type != colorType) {
            return -1;
        }
        if (reader.read(10L) != 59) {
            return -1;
        }
        if (reader.read(10L) != 114 || reader.read(10L) != 103 || reader.read(10L) != 98 || reader.read(10L) != 58) {
            return -1;
        }
        final StringBuilder sb = new StringBuilder(16);
        final List<String> rgb = new ArrayList<String>();
        while (true) {
            final int c = reader.read(10L);
            if (c == 7) {
                rgb.add(sb.toString());
                break;
            }
            if (c == 27) {
                final int next = reader.read(10L);
                if (next == 92) {
                    rgb.add(sb.toString());
                    break;
                }
                return -1;
            }
            else if ((c >= 48 && c <= 57) || (c >= 65 && c <= 90) || (c >= 97 && c <= 122)) {
                sb.append((char)c);
            }
            else {
                if (c != 47) {
                    continue;
                }
                rgb.add(sb.toString());
                sb.setLength();
            }
        }
        if (rgb.size() != 3) {
            return -1;
        }
        final double r = Integer.parseInt(rgb.get(0), 16) / ((1 << 4 * rgb.get(0).length()) - 1.0);
        final double g = Integer.parseInt(rgb.get(1), 16) / ((1 << 4 * rgb.get(1).length()) - 1.0);
        final double b = Integer.parseInt(rgb.get(2), 16) / ((1 << 4 * rgb.get(2).length()) - 1.0);
        return (int)((Math.round(r * 255.0) << 16) + (Math.round(g * 255.0) << 8) + Math.round(b * 255.0));
    }
}
