package cn.pluss.platform.util;

import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

@Slf4j
public class Base64Util {

    private static final Integer KB = 1024;

    private static final char last2byte = (char) Integer.parseInt("00000011", 2);
    private static final char last4byte = (char) Integer.parseInt("00001111", 2);
    private static final char last6byte = (char) Integer.parseInt("00111111", 2);
    private static final char lead6byte = (char) Integer.parseInt("11111100", 2);
    private static final char lead4byte = (char) Integer.parseInt("11110000", 2);
    private static final char lead2byte = (char) Integer.parseInt("11000000", 2);
    private static final char[] encodeTable = new char[]{'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', '0', '1',
            '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};

    /**
     * 将文件转成base64 字符串
     *
     * @return *
     * @throws Exception
     */

    public static String encodeBase64File(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return Base64.getEncoder().encodeToString(buffer);

    }

    /**
     * base64转inputStream
     *
     * @param base64string
     * @return
     */
    public static InputStream base64ToInputStream(String base64string) {
        ByteArrayInputStream stream = null;
        try {
            byte[] bytes1 = Base64.getDecoder().decode(base64string);
            stream = new ByteArrayInputStream(bytes1);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return stream;
    }

    /**
     * 将base64字符解码保存文件
     *
     * @param base64Code
     * @param targetPath
     * @throws Exception
     */

    public static void decoderBase64File(String base64Code, String targetPath) throws Exception {
        byte[] buffer = Base64.getDecoder().decode(base64Code);
        FileOutputStream out = new FileOutputStream(targetPath);
        out.write(buffer);
        out.close();

    }

    /**
     * 将base64字符保存文本文件
     *
     * @param base64Code
     * @param targetPath
     * @throws Exception
     */

    public static void toFile(String base64Code, String targetPath) throws Exception {

        byte[] buffer = base64Code.getBytes();
        FileOutputStream out = new FileOutputStream(targetPath);
        out.write(buffer);
        out.close();
    }

    public static MultipartFile base64ToMultipart(String base64) {
        String[] baseStrs = base64.split(",");

        byte[] b = Base64.getDecoder().decode(baseStrs[1]);

        for (int i = 0; i < b.length; ++i) {
            if (b[i] < 0) {
                b[i] += 256;
            }
        }
        return new Base64DecodedMultipartFile(b, baseStrs[0]);
    }

    /**
     *
     * @param origPicContent
     * @param desFileSize   期望文件大小，单位KB
     * @return
     */
    public static String compressPic(String origPicContent, Integer desFileSize) {
        ByteArrayInputStream in = null;
        ByteArrayOutputStream out = null;
        try {
            byte[] bytes = Base64.getDecoder().decode(origPicContent);
            while (bytes.length > desFileSize * KB) {
                in = new ByteArrayInputStream(bytes);
                out = new ByteArrayOutputStream();
                Thumbnails.of(in)
                        .scale(0.9f)
                        .outputQuality(1)
                        .toOutputStream(out);
                bytes = out.toByteArray();
            }
            return Base64.getEncoder().encodeToString(bytes).replaceAll("[\r\n]","");
        } catch (IOException e) {
            log.error ("decode buffer fail, message:{}", e.getMessage (), e);
        } finally {
            if (in != null) {
                try {
                    in.close ();
                } catch (IOException e) {
                    log.error ("ByteArrayInputStream close fail, message:{}", e.getMessage (), e);
                }
            }
            if (out != null) {
                try {
                    out.close ();
                } catch (IOException e) {
                    log.error ("ByteArrayOutputStream close fail, message:{}", e.getMessage (), e);
                }
            }
        }
        return origPicContent;
    }

    /**
     * 字符串 base64 编码
     * @param source
     * @return
     */
    public static String encode(String source){
        return Base64.getEncoder().encodeToString(source.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 字符串 base64 解码
     * @param source
     * @return
     */
    public static String decode(String source){
        try {
            return new String(Base64.getDecoder().decode(source),"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "";
        }
    }
}
