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

package com.google.common.flogger.backend;

import com.google.common.flogger.LogSite;
import java.math.BigInteger;
import java.io.IOException;
import java.util.Formatter;
import java.util.Formattable;
import java.util.Arrays;
import java.util.Locale;

public final class MessageUtils
{
    static final Locale FORMAT_LOCALE;
    
    private MessageUtils() {
    }
    
    public static String safeToString(final Object value) {
        try {
            return (value != null) ? toString(value) : "null";
        }
        catch (final RuntimeException e) {
            return getErrorString(value, e);
        }
    }
    
    private static String toString(final Object value) {
        if (!value.getClass().isArray()) {
            return String.valueOf(value);
        }
        if (value instanceof int[]) {
            return Arrays.toString((int[])value);
        }
        if (value instanceof long[]) {
            return Arrays.toString((long[])value);
        }
        if (value instanceof byte[]) {
            return Arrays.toString((byte[])value);
        }
        if (value instanceof char[]) {
            return Arrays.toString((char[])value);
        }
        if (value instanceof short[]) {
            return Arrays.toString((short[])value);
        }
        if (value instanceof float[]) {
            return Arrays.toString((float[])value);
        }
        if (value instanceof double[]) {
            return Arrays.toString((double[])value);
        }
        if (value instanceof boolean[]) {
            return Arrays.toString((boolean[])value);
        }
        return Arrays.toString((Object[])value);
    }
    
    public static void safeFormatTo(final Formattable value, final StringBuilder out, final FormatOptions options) {
        int formatFlags = options.getFlags() & 0xA2;
        if (formatFlags != 0) {
            formatFlags = ((((formatFlags & 0x20) != 0x0) ? 1 : 0) | (((formatFlags & 0x80) != 0x0) ? 2 : 0) | (((formatFlags & 0x2) != 0x0) ? 4 : 0));
        }
        final int originalLength = out.length();
        final Formatter formatter = new Formatter(out, MessageUtils.FORMAT_LOCALE);
        try {
            value.formatTo(formatter, formatFlags, options.getWidth(), options.getPrecision());
        }
        catch (final RuntimeException e) {
            out.setLength();
            try {
                formatter.out().append(getErrorString(value, e));
            }
            catch (final IOException ex) {}
        }
    }
    
    static void appendHex(final StringBuilder out, final Number number, final FormatOptions options) {
        final boolean isUpper = options.shouldUpperCase();
        final long n = number.longValue();
        if (number instanceof Long) {
            appendHex(out, n, isUpper);
        }
        else if (number instanceof Integer) {
            appendHex(out, n & 0xFFFFFFFFL, isUpper);
        }
        else if (number instanceof Byte) {
            appendHex(out, n & 0xFFL, isUpper);
        }
        else if (number instanceof Short) {
            appendHex(out, n & 0xFFFFL, isUpper);
        }
        else {
            if (!(number instanceof BigInteger)) {
                throw new IllegalStateException("unsupported number type: " + number.getClass());
            }
            final String hex = ((BigInteger)number).toString(16);
            out.append(isUpper ? hex.toUpperCase(MessageUtils.FORMAT_LOCALE) : hex);
        }
    }
    
    private static void appendHex(final StringBuilder out, final long n, final boolean isUpper) {
        if (n == 0L) {
            out.append("0");
        }
        else {
            final String hexChars = isUpper ? "0123456789ABCDEF" : "0123456789abcdef";
            for (int shift = 63 - Long.numberOfLeadingZeros(n) & 0xFFFFFFFC; shift >= 0; shift -= 4) {
                out.append(hexChars.charAt((int)(n >>> shift & 0xFL)));
            }
        }
    }
    
    private static String getErrorString(final Object value, final RuntimeException e) {
        String errorMessage;
        try {
            errorMessage = e.toString();
        }
        catch (final RuntimeException runtimeException) {
            errorMessage = runtimeException.getClass().getSimpleName();
        }
        return "{" + value.getClass().getName() + "@" + System.identityHashCode(value) + ": " + errorMessage + "}";
    }
    
    public static boolean appendLogSite(final LogSite logSite, final StringBuilder out) {
        if (logSite == LogSite.INVALID) {
            return false;
        }
        out.append(logSite.getClassName()).append('.').append(logSite.getMethodName()).append(':').append(logSite.getLineNumber());
        return true;
    }
    
    static {
        FORMAT_LOCALE = Locale.ROOT;
    }
}
