package be.iminds.ilabt.jfed.util;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;

import java.io.*;
import java.util.zip.DeflaterInputStream;
import java.util.zip.InflaterInputStream;

/**
 * DataConversionUtils
 */
public class DataConversionUtils {
    private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(DataConversionUtils.class);

    /**
     * note: from command line this can also be done: echo 'DATA' | base64 --decode | openssl zlib -d
     *
     * @param s A base64 encoded string, containing compressed data. Compression is as specified in RFC 1950
     * @return the decoded string
     */
    public static String decompressFromBase64(String s) {
        StringBuilder res = new StringBuilder();
        if (s.length() == 0)
            return s;
        try {
            byte[] b = Base64.decodeBase64(StringUtils.getBytesUtf8(s));
            BufferedReader br =
                    new BufferedReader(new InputStreamReader(new InflaterInputStream(new ByteArrayInputStream(b))));
            String line = br.readLine();
            while (line != null) {
                res.append(line);
                line = br.readLine();
            }
            br.close();
        } catch (Exception e) {
            LOG.warn("Could not decompress string of length={}", s.length(), e);
            return null;
        }

        return res.toString();
    }

    /* reverse operation */
    public static String compressToBase64(String s) {
        if (s.isEmpty())
            return s;

        try {
            byte[] b = StringUtils.getBytesUtf8(s);
            InputStream is = new DeflaterInputStream(new ByteArrayInputStream(b));

            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            int nRead;
            byte[] data = new byte[1024];
            while ((nRead = is.read(data, 0, data.length)) != -1) {
                buffer.write(data, 0, nRead);
            }
            buffer.close();

            return new String(Base64.encodeBase64(buffer.toByteArray()), "UTF-8");
        } catch (Exception e) {
            LOG.warn("Could not decompress string of length=" + s.length());
            //e.printStackTrace();
            return null;
        }
    }

    public static byte[] decodeBase64(String s) {
        return Base64.decodeBase64(StringUtils.getBytesUtf8(s));
    }

    public static String encodeBase64(byte[] b) {
        return Base64.encodeBase64String(b);
    }
}
