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

package org.fusesource.jansi;

import java.io.FileInputStream;
import java.io.Reader;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.io.InputStream;
import java.io.Closeable;
import java.util.Properties;
import java.io.PrintStream;
import org.fusesource.jansi.internal.CLibrary;
import org.fusesource.jansi.internal.MingwSupport;
import org.fusesource.jansi.internal.Kernel32;
import java.io.IOException;
import java.io.File;
import org.fusesource.jansi.internal.JansiLoader;

public class AnsiMain
{
    public static void main(final String... args) throws IOException {
        System.out.println("Jansi " + getJansiVersion());
        System.out.println();
        System.out.println("library.jansi.path= " + System.getProperty("library.jansi.path", ""));
        System.out.println("library.jansi.version= " + System.getProperty("library.jansi.version", ""));
        final boolean loaded = JansiLoader.initialize();
        if (loaded) {
            System.out.println("Jansi native library loaded from " + JansiLoader.getNativeLibraryPath());
            if (JansiLoader.getNativeLibrarySourceUrl() != null) {
                System.out.println("   which was auto-extracted from " + JansiLoader.getNativeLibrarySourceUrl());
            }
        }
        else {
            final String prev = System.getProperty("jansi.graceful");
            try {
                System.setProperty("jansi.graceful", "false");
                JansiLoader.initialize();
            }
            catch (final Throwable e) {
                e.printStackTrace(System.out);
            }
            finally {
                if (prev != null) {
                    System.setProperty("jansi.graceful", prev);
                }
                else {
                    System.clearProperty("jansi.graceful");
                }
            }
        }
        System.out.println();
        System.out.println("os.name= " + System.getProperty("os.name") + ", os.version= " + System.getProperty("os.version") + ", os.arch= " + System.getProperty("os.arch"));
        System.out.println("file.encoding= " + System.getProperty("file.encoding"));
        System.out.println("sun.stdout.encoding= " + System.getProperty("sun.stdout.encoding") + ", sun.stderr.encoding= " + System.getProperty("sun.stderr.encoding"));
        System.out.println("stdout.encoding= " + System.getProperty("stdout.encoding") + ", stderr.encoding= " + System.getProperty("stderr.encoding"));
        System.out.println("java.version= " + System.getProperty("java.version") + ", java.vendor= " + System.getProperty("java.vendor") + ", java.home= " + System.getProperty("java.home"));
        System.out.println("Console: " + System.console());
        System.out.println();
        System.out.println("jansi.graceful= " + System.getProperty("jansi.graceful", ""));
        System.out.println("jansi.mode= " + System.getProperty("jansi.mode", ""));
        System.out.println("jansi.out.mode= " + System.getProperty("jansi.out.mode", ""));
        System.out.println("jansi.err.mode= " + System.getProperty("jansi.err.mode", ""));
        System.out.println("jansi.colors= " + System.getProperty("jansi.colors", ""));
        System.out.println("jansi.out.colors= " + System.getProperty("jansi.out.colors", ""));
        System.out.println("jansi.err.colors= " + System.getProperty("jansi.err.colors", ""));
        System.out.println("jansi.passthrough= " + AnsiConsole.getBoolean("jansi.passthrough"));
        System.out.println("jansi.strip= " + AnsiConsole.getBoolean("jansi.strip"));
        System.out.println("jansi.force= " + AnsiConsole.getBoolean("jansi.force"));
        System.out.println("jansi.noreset= " + AnsiConsole.getBoolean("jansi.noreset"));
        System.out.println(Ansi.DISABLE + "= " + AnsiConsole.getBoolean(Ansi.DISABLE));
        System.out.println();
        System.out.println("IS_WINDOWS: " + AnsiConsole.IS_WINDOWS);
        if (AnsiConsole.IS_WINDOWS) {
            System.out.println("IS_CONEMU: " + AnsiConsole.IS_CONEMU);
            System.out.println("IS_CYGWIN: " + AnsiConsole.IS_CYGWIN);
            System.out.println("IS_MSYSTEM: " + AnsiConsole.IS_MSYSTEM);
        }
        System.out.println();
        diagnoseTty(false);
        diagnoseTty(true);
        AnsiConsole.systemInstall();
        System.out.println();
        System.out.println("Resulting Jansi modes for stout/stderr streams:");
        System.out.println("  - System.out: " + AnsiConsole.out().toString());
        System.out.println("  - System.err: " + AnsiConsole.err().toString());
        System.out.println("Processor types description:");
        for (final AnsiType type : AnsiType.values()) {
            System.out.println("  - " + type + ": " + type.getDescription());
        }
        System.out.println("Colors support description:");
        for (final AnsiColors colors : AnsiColors.values()) {
            System.out.println("  - " + colors + ": " + colors.getDescription());
        }
        System.out.println("Modes description:");
        for (final AnsiMode mode : AnsiMode.values()) {
            System.out.println("  - " + mode + ": " + mode.getDescription());
        }
        try {
            System.out.println();
            testAnsi(false);
            testAnsi(true);
            if (args.length == 0) {
                printJansiLogoDemo();
                return;
            }
            System.out.println();
            if (args.length == 1) {
                final File f = new File(args[0]);
                if (f.exists()) {
                    System.out.println(Ansi.ansi().bold().a("\"" + args[0] + "\" content:").reset());
                    writeFileContent(f);
                    return;
                }
            }
            System.out.println(Ansi.ansi().bold().a("original args:").reset());
            int i = 1;
            for (final String arg : args) {
                AnsiConsole.system_out.print(i++ + ": ");
                AnsiConsole.system_out.println(arg);
            }
            System.out.println(Ansi.ansi().bold().a("Jansi filtered args:").reset());
            i = 1;
            for (final String arg : args) {
                System.out.print(i++ + ": ");
                System.out.println(arg);
            }
        }
        finally {
            AnsiConsole.systemUninstall();
        }
    }
    
    private static String getJansiVersion() {
        final Package p = AnsiMain.class.getPackage();
        return (p == null) ? null : p.getImplementationVersion();
    }
    
    private static void diagnoseTty(final boolean stderr) {
        int isatty;
        int width;
        if (AnsiConsole.IS_WINDOWS) {
            final long console = Kernel32.GetStdHandle(stderr ? Kernel32.STD_ERROR_HANDLE : Kernel32.STD_OUTPUT_HANDLE);
            final int[] mode = { 0 };
            isatty = Kernel32.GetConsoleMode(console, mode);
            if ((AnsiConsole.IS_CONEMU || AnsiConsole.IS_CYGWIN || AnsiConsole.IS_MSYSTEM) && isatty == 0) {
                final MingwSupport mingw = new MingwSupport();
                final String name = mingw.getConsoleName(!stderr);
                if (name != null && !name.isEmpty()) {
                    isatty = 1;
                    width = mingw.getTerminalWidth(name);
                }
                else {
                    isatty = 0;
                    width = 0;
                }
            }
            else {
                final Kernel32.CONSOLE_SCREEN_BUFFER_INFO info = new Kernel32.CONSOLE_SCREEN_BUFFER_INFO();
                Kernel32.GetConsoleScreenBufferInfo(console, info);
                width = info.windowWidth();
            }
        }
        else {
            final int fd = stderr ? CLibrary.STDERR_FILENO : CLibrary.STDOUT_FILENO;
            isatty = (CLibrary.LOADED ? CLibrary.isatty(fd) : 0);
            final CLibrary.WinSize ws = new CLibrary.WinSize();
            CLibrary.ioctl(fd, CLibrary.TIOCGWINSZ, ws);
            width = ws.ws_col;
        }
        System.out.println("isatty(STD" + (stderr ? "ERR" : "OUT") + "_FILENO): " + isatty + ", System." + (stderr ? "err" : "out") + " " + ((isatty == 0) ? "is *NOT*" : "is") + " a terminal");
        System.out.println("width(STD" + (stderr ? "ERR" : "OUT") + "_FILENO): " + width);
    }
    
    private static void testAnsi(final boolean stderr) {
        final PrintStream s = stderr ? System.err : System.out;
        s.print("test on System." + (stderr ? "err" : "out") + ":");
        for (final Ansi.Color c : Ansi.Color.values()) {
            s.print(" " + Ansi.ansi().fg(c) + c + Ansi.ansi().reset());
        }
        s.println();
        s.print("            bright:");
        for (final Ansi.Color c : Ansi.Color.values()) {
            s.print(" " + Ansi.ansi().fgBright(c) + c + Ansi.ansi().reset());
        }
        s.println();
        s.print("              bold:");
        for (final Ansi.Color c : Ansi.Color.values()) {
            s.print(" " + Ansi.ansi().bold().fg(c) + c + Ansi.ansi().reset());
        }
        s.println();
        s.print("             faint:");
        for (final Ansi.Color c : Ansi.Color.values()) {
            s.print(" " + Ansi.ansi().a(Ansi.Attribute.INTENSITY_FAINT).fg(c) + c + Ansi.ansi().reset());
        }
        s.println();
        s.print("        bold+faint:");
        for (final Ansi.Color c : Ansi.Color.values()) {
            s.print(" " + Ansi.ansi().bold().a(Ansi.Attribute.INTENSITY_FAINT).fg(c) + c + Ansi.ansi().reset());
        }
        s.println();
        Ansi ansi = Ansi.ansi();
        ansi.a("        256 colors: ");
        for (int i = 0; i < 216; ++i) {
            if (i > 0 && i % 36 == 0) {
                ansi.reset();
                ansi.newline();
                ansi.a("                    ");
            }
            else if (i > 0 && i % 6 == 0) {
                ansi.reset();
                ansi.a("  ");
            }
            final int a0 = i % 6;
            final int a2 = i / 6 % 6;
            final int a3 = i / 36;
            ansi.bg(16 + a0 + a3 * 6 + a2 * 36).a(' ');
        }
        ansi.reset();
        s.println(ansi);
        ansi = Ansi.ansi();
        ansi.a("         truecolor: ");
        for (int i = 0; i < 256; ++i) {
            if (i > 0 && i % 48 == 0) {
                ansi.reset();
                ansi.newline();
                ansi.a("                    ");
            }
            final int r = 255 - i;
            final int g = (i * 2 > 255) ? (255 - 2 * i) : (2 * i);
            final int b = i;
            ansi.bgRgb(r, g, b).fgRgb(255 - r, 255 - g, 255 - b).a((i % 2 == 0) ? '/' : '\\');
        }
        ansi.reset();
        s.println(ansi);
    }
    
    private static String getPomPropertiesVersion(final String path) throws IOException {
        final InputStream in = AnsiMain.class.getResourceAsStream("/META-INF/maven/" + path + "/pom.properties");
        if (in == null) {
            return null;
        }
        try {
            final Properties p = new Properties();
            p.load(in);
            return p.getProperty("version");
        }
        finally {
            closeQuietly(in);
        }
    }
    
    private static void printJansiLogoDemo() throws IOException {
        final BufferedReader in = new BufferedReader(new InputStreamReader(AnsiMain.class.getResourceAsStream("jansi.txt"), StandardCharsets.UTF_8));
        try {
            String l;
            while ((l = in.readLine()) != null) {
                System.out.println(l);
            }
        }
        finally {
            closeQuietly(in);
        }
    }
    
    private static void writeFileContent(final File f) throws IOException {
        final InputStream in = new FileInputStream(f);
        try {
            final byte[] buf = new byte[1024];
            int l = 0;
            while ((l = in.read(buf)) >= 0) {
                System.out.write(buf, 0, l);
            }
        }
        finally {
            closeQuietly(in);
        }
    }
    
    private static void closeQuietly(final Closeable c) {
        try {
            c.close();
        }
        catch (final IOException ioe) {
            ioe.printStackTrace(System.err);
        }
    }
}
