package com.apobates.forum.trident.controller.helper;

import java.io.File;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.Optional;
import com.apobates.forum.core.api.TopicFileCacheHandler;
import com.apobates.forum.utils.image.OverlayBox.OverlayConfig;
import com.apobates.forum.utils.zxing.GeneralQRCode;
import com.apobates.forum.utils.zxing.GeneralQRCode.GeneralQRCodeBuilder;
import com.apobates.forum.utils.zxing.GeneralQRCode.ImageType;
/**
 * 生成二维码的文件句柄
 * 
 * @author xiaofanku
 * @since 20200326
 */
public class TopicQRCodeFileCacheHandler implements TopicFileCacheHandler {
	private final GeneralQRCodeBuilder qRCodeBuilder;
	private final File logoPath;
	private final OverlayConfig config;
	
	private TopicQRCodeFileCacheHandler(GeneralQRCodeBuilder qRCodeBuilder, File logoPath, OverlayConfig config) {
		this.qRCodeBuilder = qRCodeBuilder;
		this.logoPath = logoPath;
		this.config = config;
	}
	//
	@Override
	public Optional<File> create() {
		try {
			GeneralQRCode qc = qRCodeBuilder.build();
			File tmpFile = createTempFile(qc.getImage().getType());
			if(null == logoPath){ //没有设置logo图片
				qc.toFile(tmpFile);
			}else{ //有设置logo图片
				try(PipedOutputStream outputStream = new PipedOutputStream(); PipedInputStream inputStream = new PipedInputStream(outputStream)){ //20200329@AutoCloseable
					qc.toStream(outputStream);
					try{
						config.image(logoPath).toFile(inputStream, tmpFile.toPath());
					}catch(NullPointerException e){
						OverlayConfig.getDefault().isContinueSave(true).image(logoPath).toFile(inputStream, tmpFile.toPath());
					}
				}
			}
			return Optional.ofNullable(tmpFile);
		} catch (Exception e) {
			return Optional.empty(); //.failure(e.getMessage());
		}
	}
	//https://github.com/kenglxn/QRGen/blob/master/core/src/main/java/net/glxn/qrgen/core/AbstractQRCode.java
	private File createTempFile(String imageType) throws IOException {
		File file = File.createTempFile("QRCode", "." + imageType);
		file.deleteOnExit();
		return file;
	}
	/**
	 * 使用二维码内容初始化一个内部包装类
	 * 
	 * @param content
	 * @return
	 */
	public static WrapQRCodeBuilder from(String content){
		return new WrapQRCodeBuilder(content);
	}
	/**
	 * 内部包装类.主要包装:二维码主类的构造者类
	 * 
	 * @author xiaofanku
	 * @since 20200326
	 */
	public static class WrapQRCodeBuilder{
		private final GeneralQRCodeBuilder qrbuilder;
		private final File logoPath;
		private final OverlayConfig config;
		/**
		 * 用二维码的内容初始化
		 * 
		 * @param content
		 */
		public WrapQRCodeBuilder(String content){
			this.qrbuilder = new GeneralQRCodeBuilder(content);
			this.logoPath = null;
			this.config = null;
		}
		
		private WrapQRCodeBuilder(GeneralQRCodeBuilder qrbuilder, File logoPath, OverlayConfig config){
			this.qrbuilder = qrbuilder;
			this.logoPath = logoPath;
			this.config = config;
		}
		/**
		 * 设置二维码的尺码
		 * 
		 * @param width  
		 * @param height 
		 * @return
		 */
		public WrapQRCodeBuilder scale(int width, int height){
			GeneralQRCodeBuilder tmp = qrbuilder.withSize(width, height);
			return new WrapQRCodeBuilder(tmp, logoPath, config);
		}
		/**
		 * 设置二维码图片的文件类型
		 * 
		 * @param type
		 * @return
		 */
		public WrapQRCodeBuilder format(ImageType type){
			GeneralQRCodeBuilder tmp = qrbuilder.formatImage(type);
			return new WrapQRCodeBuilder(tmp, logoPath, config);
		}
		/**
		 * 为二维码增加logo图片<br/>
		 * logo图片面积大于100X100可能导致无法解析<br/>
		 * 
		 * @param logoPath
		 * @return
		 */
		public WrapQRCodeBuilder logo(File logoPath){
			return new WrapQRCodeBuilder(qrbuilder, logoPath, config);
		}
		/**
		 * 设置二维码中的logo图片遮盖层
		 * 
		 * @param config
		 * @return
		 */
		public WrapQRCodeBuilder overlay(OverlayConfig config){
			return new WrapQRCodeBuilder(qrbuilder, logoPath, config);
		}
		/**
		 * 实例化一个话题文件缓存处理句柄
		 * 
		 * @return
		 */
		public TopicQRCodeFileCacheHandler handler(){
			return new TopicQRCodeFileCacheHandler(this.qrbuilder, this.logoPath, this.config);
		}
	}
}
