package me.qwq.doghouse.flexmark.ext.plantuml;

public class PlantUMLEncode {
    //进行base64映射的字符数组
    private final static char[] CHARS = {
            '0','1','2','3','4','5','6','7','8','9',
            'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
            'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
            '-', '_'};

    /**
     * 编码
     * @param code
     * @return
     */
    public String encode(byte[] code){
        if (code == null || code.length == 0)
            return null;
        int length = code.length, mod = length % 3, div = length / 3;
        char[] result = new char[(mod == 0 ? div : (div + 1)) * 4];
        for(int i = 0;i <= div; i++){
            if (i == div && mod == 0) break;
            int temp1 = i * 3, temp2 = i * 4;
            byte a1 = code[temp1],
                 a2 = i == div && mod == 1 ? (byte)0 : code[temp1 + 1],
                 a3 = i == div && mod >= 1 ? (byte)0 : code[temp1 + 2];
            result[temp2] = CHARS[((a1 & 0xFC) >> 2)];
            result[temp2 + 1] = CHARS[(a1 & 0x03) << 4 | (a2 & 0xF0) >> 4];
            if (i != div || mod == 0) {
                result[temp2 + 2] = CHARS[(a2 & 0x0F) << 2 | (a3 & 0xC0) >> 6];
                result[temp2 + 3] = CHARS[(a3 & 0x3F)];
            }
            else if (mod != 0) {
                result[temp2 + 2] = mod == 2 ? 
                        CHARS[(a2 & 0x0F) << 2 | (a3 & 0xC0) >> 6]:
                        '=';
                result[temp2 + 3] = '=';
            }
        }
        return new String(result);
    }

    /**
     * 获取编码器
     * @return
     */
    public static PlantUMLEncode getEncoder(){
        return new PlantUMLEncode();
    }
}