/*
 * Decompiled with CFR 0.152.
 */
package org.jivesoftware.smack.util.stringencoder;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jivesoftware.smack.util.stringencoder.StringEncoder;

public class Base32 {
    private static final StringEncoder base32Stringencoder = new StringEncoder(){

        @Override
        public String encode(String string) {
            return Base32.encode(string);
        }

        @Override
        public String decode(String string) {
            return Base32.decode(string);
        }
    };
    private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ2345678";

    public static StringEncoder getStringEncoder() {
        return base32Stringencoder;
    }

    public static String decode(String str) {
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        byte[] raw = str.getBytes();
        for (int i = 0; i < raw.length; ++i) {
            char c = (char)raw[i];
            if (Character.isWhitespace(c)) continue;
            c = Character.toUpperCase(c);
            bs.write((byte)c);
        }
        while (bs.size() % 8 != 0) {
            bs.write(56);
        }
        byte[] in = bs.toByteArray();
        bs.reset();
        DataOutputStream ds = new DataOutputStream(bs);
        for (int i = 0; i < in.length / 8; ++i) {
            char c;
            short[] s = new short[8];
            int[] t = new int[5];
            int padlen = 8;
            for (int j = 0; j < 8 && (c = (char)in[i * 8 + j]) != '8'; ++j) {
                s[j] = (short)ALPHABET.indexOf(in[i * 8 + j]);
                if (s[j] < 0) {
                    return null;
                }
                --padlen;
            }
            int blocklen = Base32.paddingToLen(padlen);
            if (blocklen < 0) {
                return null;
            }
            t[0] = s[0] << 3 | s[1] >> 2;
            t[1] = (s[1] & 3) << 6 | s[2] << 1 | s[3] >> 4;
            t[2] = (s[3] & 0xF) << 4 | s[4] >> 1 & 0xF;
            t[3] = s[4] << 7 | s[5] << 2 | s[6] >> 3;
            t[4] = (s[6] & 7) << 5 | s[7];
            try {
                for (int j = 0; j < blocklen; ++j) {
                    ds.writeByte((byte)(t[j] & 0xFF));
                }
                continue;
            }
            catch (IOException e) {
                // empty catch block
            }
        }
        return new String(bs.toByteArray());
    }

    public static String encode(String str) {
        byte[] b = str.getBytes();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        for (int i = 0; i < (b.length + 4) / 5; ++i) {
            short[] s = new short[5];
            int[] t = new int[8];
            int blocklen = 5;
            for (int j = 0; j < 5; ++j) {
                if (i * 5 + j < b.length) {
                    s[j] = (short)(b[i * 5 + j] & 0xFF);
                    continue;
                }
                s[j] = 0;
                --blocklen;
            }
            int padlen = Base32.lenToPadding(blocklen);
            t[0] = (byte)(s[0] >> 3 & 0x1F);
            t[1] = (byte)((s[0] & 7) << 2 | s[1] >> 6 & 3);
            t[2] = (byte)(s[1] >> 1 & 0x1F);
            t[3] = (byte)((s[1] & 1) << 4 | s[2] >> 4 & 0xF);
            t[4] = (byte)((s[2] & 0xF) << 1 | s[3] >> 7 & 1);
            t[5] = (byte)(s[3] >> 2 & 0x1F);
            t[6] = (byte)((s[3] & 3) << 3 | s[4] >> 5 & 7);
            t[7] = (byte)(s[4] & 0x1F);
            for (int j = 0; j < t.length - padlen; ++j) {
                char c = ALPHABET.charAt(t[j]);
                os.write(c);
            }
        }
        return new String(os.toByteArray());
    }

    private static int lenToPadding(int blocklen) {
        switch (blocklen) {
            case 1: {
                return 6;
            }
            case 2: {
                return 4;
            }
            case 3: {
                return 3;
            }
            case 4: {
                return 1;
            }
            case 5: {
                return 0;
            }
        }
        return -1;
    }

    private static int paddingToLen(int padlen) {
        switch (padlen) {
            case 6: {
                return 1;
            }
            case 4: {
                return 2;
            }
            case 3: {
                return 3;
            }
            case 1: {
                return 4;
            }
            case 0: {
                return 5;
            }
        }
        return -1;
    }
}
