package com.upyuns.platform.rs.universal.service;

import com.upyuns.platform.rs.universal.interceptor.CaptchaException;
import com.upyuns.platform.rs.universal.dto.CaptchaBaseParam;
import com.upyuns.platform.rs.universal.vo.CaptchaBaseVO;
import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.List;

/**
 * 图行验证码抽象方法

 */
public abstract class AbstractCaptcha {
    protected static final String URL_PREFIX_HTTP = "http://";
    protected static final String URL_PREFIX_HTTPS = "https://";
    protected static final String IMAGE_TYPE_PNG = "png";

    /** 滑块拼图图片地址 */
    private String jigsawUrlOrPath;
    /** 点选文字 字体总个数 */
    private int wordTotalCount = 4;
    /** 点选文字 字体颜色是否随机 */
    private boolean fontColorRandom = Boolean.TRUE;

    public abstract CaptchaBaseVO create(CaptchaBaseParam captchaParam);

    public abstract boolean verification(List<Point> pointList, List<Point> pointList1);

    /**
     *
     * 获取原生图片
     * @param urlOrPath
     * @return
     */
    protected static BufferedImage getBufferedImage (String urlOrPath) {
        if (StringUtils.isBlank(urlOrPath)) {
            throw new CaptchaException("urlOrPath is empty.");
        }
        BufferedImage sampleImage = null;
        try {
            if (urlOrPath.startsWith(URL_PREFIX_HTTP) || urlOrPath.startsWith(URL_PREFIX_HTTPS)) {
                sampleImage = ImageIO.read(new URL(urlOrPath));
            } else {
                sampleImage = ImageIO.read(new File(urlOrPath));
            }
        } catch (IOException e ){
            throw new CaptchaException("urlOrPath is url or path error.");
        }

        // todo  可以考虑验证下尺寸 300 * 155
        return sampleImage;
    }

    /**
     * 图片转base64 字符串
     * @param templateImage
     * @return
     */
    protected String getImageToBase64Str (BufferedImage templateImage){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            ImageIO.write(templateImage, "png", baos);
        } catch (IOException e) {
            throw new CaptchaException("ImageIO.write  is error", e);
        }
        byte[] bytes = baos.toByteArray();
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encodeBuffer(bytes).trim().replaceAll("\n", "").replaceAll("\r", "");
    }

    public String getJigsawUrlOrPath() {
        return jigsawUrlOrPath;
    }

    public void setJigsawUrlOrPath(String jigsawUrlOrPath) {
        this.jigsawUrlOrPath = jigsawUrlOrPath;
    }

    public int getWordTotalCount() {
        return wordTotalCount;
    }

    public void setWordTotalCount(int wordTotalCount) {
        this.wordTotalCount = wordTotalCount;
    }

    public boolean isFontColorRandom() {
        return fontColorRandom;
    }

    public void setFontColorRandom(boolean fontColorRandom) {
        this.fontColorRandom = fontColorRandom;
    }
}
