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

package org.fusesource.jansi.internal;

import java.lang.reflect.Field;
import java.lang.reflect.Constructor;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import java.util.regex.Matcher;
import java.io.IOException;
import java.io.FileDescriptor;
import java.io.File;
import java.util.regex.Pattern;

public class MingwSupport
{
    private final String sttyCommand;
    private final String ttyCommand;
    private final Pattern columnsPatterns;
    
    public MingwSupport() {
        String tty = null;
        String stty = null;
        final String path = System.getenv("PATH");
        if (path != null) {
            final String[] split;
            final String[] paths = split = path.split(File.pathSeparator);
            for (final String p : split) {
                final File ttyFile = new File(p, "tty.exe");
                if (tty == null && ttyFile.canExecute()) {
                    tty = ttyFile.getAbsolutePath();
                }
                final File sttyFile = new File(p, "stty.exe");
                if (stty == null && sttyFile.canExecute()) {
                    stty = sttyFile.getAbsolutePath();
                }
            }
        }
        if (tty == null) {
            tty = "tty.exe";
        }
        if (stty == null) {
            stty = "stty.exe";
        }
        this.ttyCommand = tty;
        this.sttyCommand = stty;
        this.columnsPatterns = Pattern.compile("\\bcolumns\\s+(\\d+)\\b");
    }
    
    public String getConsoleName(final boolean stdout) {
        try {
            final Process p = new ProcessBuilder(new String[] { this.ttyCommand }).redirectInput(this.getRedirect(stdout ? FileDescriptor.out : FileDescriptor.err)).start();
            final String result = waitAndCapture(p);
            if (p.exitValue() == 0) {
                return result.trim();
            }
        }
        catch (final Throwable t) {
            if ("java.lang.reflect.InaccessibleObjectException".equals(t.getClass().getName())) {
                System.err.println("MINGW support requires --add-opens java.base/java.lang=ALL-UNNAMED");
            }
        }
        return null;
    }
    
    public int getTerminalWidth(final String name) {
        try {
            final Process p = new ProcessBuilder(new String[] { this.sttyCommand, "-F", name, "-a" }).start();
            final String result = waitAndCapture(p);
            if (p.exitValue() != 0) {
                throw new IOException("Error executing '" + this.sttyCommand + "': " + result);
            }
            final Matcher matcher = this.columnsPatterns.matcher(result);
            if (matcher.find()) {
                return Integer.parseInt(matcher.group(1));
            }
            throw new IOException("Unable to parse columns");
        }
        catch (final Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    private static String waitAndCapture(final Process p) throws IOException, InterruptedException {
        final ByteArrayOutputStream bout = new ByteArrayOutputStream();
        try (final InputStream in = p.getInputStream();
             final InputStream err = p.getErrorStream()) {
            int c;
            while ((c = in.read()) != -1) {
                bout.write(c);
            }
            while ((c = err.read()) != -1) {
                bout.write(c);
            }
            p.waitFor();
        }
        return bout.toString();
    }
    
    private ProcessBuilder.Redirect getRedirect(final FileDescriptor fd) throws ReflectiveOperationException {
        final Class<?> rpi = Class.forName("java.lang.ProcessBuilder$RedirectPipeImpl");
        final Constructor<?> cns = rpi.getDeclaredConstructor((Class<?>[])new Class[0]);
        cns.setAccessible(true);
        final ProcessBuilder.Redirect input = (ProcessBuilder.Redirect)cns.newInstance(new Object[0]);
        final Field f = rpi.getDeclaredField("fd");
        f.setAccessible(true);
        f.set(input, fd);
        return input;
    }
}
