package com.product.file.util;

import com.alibaba.druid.util.StringUtils;
import com.product.core.config.Global;
import com.product.core.exception.BaseException;
import com.product.core.spring.context.SpringMVCContextHolder;
import com.product.file.config.FileCode;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.ExternalOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeException;
import org.artofsolving.jodconverter.office.OfficeManager;

import java.io.File;
import java.util.Properties;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Copyright 漏 6c
 * @Date: 2021-03-01 13:59
 * @Author: 6c
 * @Description:
 */
public class PdfConcurrenceUtil {

    private static BlockingQueue<OfficeManager> officeManagerQueue = new LinkedBlockingQueue<>();

    // 瀹夎鍦板潃
    private static String openOfficeHome;
    // 绔彛鍙蜂俊鎭紝閫楀彿鍒嗗壊
    private static String portInfo;
    // 鍗曚釜浠诲姟鎵ц瓒呮椂鏃堕棿锛屽崟浣嶏細姣
    private static long taskTimeout;
    // 鍗曚釜浠诲姟鎺掗槦瓒呮椂鏃堕棿锛屽崟浣嶏細姣
    private static long queueTimeout;

    static {
        SpringMVCContextHolder.getSystemLogger().info("鍒濆鍖�->");
        //init();
    }

    private PdfConcurrenceUtil() {}

    /**
     * 鍒濆鍖栬浆鎹㈡湇鍔�
     */
    public static boolean init() {
    	if(!Global.getPropertyToBoolean("open.office.isEnable", "true")) {//涓嶅惎鐢╫epn office杞崲
    		return true;
    	}
        SpringMVCContextHolder.getSystemLogger().info("鍒濆鍖栬浆鎹㈡湇鍔�->");
        openOfficeHome = Global.getSystemConfig("open.office.home","");
        portInfo = Global.getSystemConfig("open.office.port.info","");
        taskTimeout = StringUtils.isEmpty(Global.getSystemConfig("open.office.task.timeout","")) ? 1000 * 60 *5 : Long.parseLong(Global.getSystemConfig("open.office.task.timeout",""));
        queueTimeout = StringUtils.isEmpty(Global.getSystemConfig("open.office.queue.timeout","")) ? 1000 * 60 *5 : Long.parseLong(Global.getSystemConfig("open.office.queue.timeout",""));

        String[] portArr = portInfo.split(",");
        for (String port : portArr) {
            if (StringUtils.isEmpty(port)) {
                continue;
            }
            try {
                OfficeManager officeManager = start(Integer.parseInt(port));
                if (officeManager != null) {
                    officeManagerQueue.put(officeManager);
                } else {
                    SpringMVCContextHolder.getSystemLogger().error(String.format("绔彛%s鍚姩澶辫触", port));
                }
            } catch (InterruptedException e) {
                SpringMVCContextHolder.getSystemLogger().error(String.format("%s,port:%s", FileCode.INIT_TRANSFER_SERVER_FAIL.getText(), port) +  e.getMessage());
            }
        }
        SpringMVCContextHolder.getSystemLogger().info("褰撳墠杞崲闃熷垪涓鍙f暟锛�" + officeManagerQueue.size());
        return true;
    }

    /**
     * 寮€鍚柊鐨刼penoffice鐨勮繘绋�
     * @param port
     * @return
     */
    private static OfficeManager start(int port) {
        try {
            SpringMVCContextHolder.getSystemLogger().info("curPort: " + port);
            OfficeManager officeManager = reconnect(port);
            if (officeManager == null) {
                DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
                configuration.setOfficeHome(openOfficeHome);
                configuration.setPortNumbers(port);
                configuration.setTaskExecutionTimeout(taskTimeout);
                configuration.setTaskQueueTimeout(queueTimeout);
                SpringMVCContextHolder.getSystemLogger().info( "1.鍚姩"+port);
                officeManager = configuration.buildOfficeManager();
                SpringMVCContextHolder.getSystemLogger().info("2.鍚姩"+port);
                officeManager.start(); // 鍚姩鏈嶅姟
                SpringMVCContextHolder.getSystemLogger().info( "3.鍚姩鎴愬姛"+ port);
            }
            return officeManager;
        } catch (Exception e) {
        	e.printStackTrace();
            SpringMVCContextHolder.getSystemLogger().error(String.format("%s:%s", FileCode.INIT_TRANSFER_SERVER_FAIL.getText(), port) + e.getMessage());
        }
        return null;
    }

    /**
     * 灏濊瘯杩炴帴openoffice鐨勫凡瀛樺湪鐨勬湇鍔″櫒
     * @param port
     * @return
     */
    private static OfficeManager reconnect(int port) {
        try {
            ExternalOfficeManagerConfiguration externalProcessOfficeManager = new ExternalOfficeManagerConfiguration();
            externalProcessOfficeManager.setConnectOnStart(true);
            externalProcessOfficeManager.setPortNumber(port);
            OfficeManager officeManager = externalProcessOfficeManager.buildOfficeManager();
            officeManager.start();
            return officeManager;
        } catch (OfficeException e) {
            SpringMVCContextHolder.getSystemLogger().info(String.format("%s,port:%s", FileCode.NO_EXISTS_TRANSFER_PORT.getText(), port));
            return null;
        }
    }

    /**
     * 閿€姣佽繘绋�
     */
    private static void destory() {
        for (OfficeManager officeManager : officeManagerQueue) {
            stop(officeManager);
        }
    }

    /**
     * 浣跨敤瀹岄渶瑕佸叧闂杩涚▼
     * @param officeManager
     */
    private static void stop(OfficeManager officeManager) {
        SpringMVCContextHolder.getSystemLogger().info("鍏抽棴OpenOffice鏈嶅姟");
        try {
            if (officeManager != null)
                officeManager.stop();
        } catch (Exception e) {
            SpringMVCContextHolder.getSystemLogger().error("鍏抽棴OpenOffice鏈嶅姟鍑洪敊" + e);
        }
    }

    /**
     * 杞崲pdf
     * @param input
     * @param output
     * @return
     */
    @Deprecated
    public static File convertToPdf(String input, String output) throws Exception {
        File inputFile = null;
        File outFile = null;
        OfficeManager officeManager = null;
        try {
            officeManager = officeManagerQueue.take();
            inputFile = new File(input);
            outFile = new File(output);
            SpringMVCContextHolder.getSystemLogger().info("寮€濮嬭浆鎹㈡枃妗o細" + input + "=>" + output);
            OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
            converter.convert(inputFile, outFile); // 杞崲鏂囨。
        }catch (Exception e) {
            outFile = null;
            throw e;
        } finally {
            SpringMVCContextHolder.getSystemLogger().info("缁撴潫杞崲鏂囨。");
            if (officeManager != null) {
                try {
                    officeManagerQueue.put(officeManager);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return outFile;
    }
    /**
     * 杞崲pdf
     * @param input
     * @param output
     * @return
     */
    public static File convertToPdf(String input, String output,String officeType) throws Exception {
        File inputFile = null;
        File outFile = null;
        OfficeManager officeManager = null;
        try {
        	if(Global.getPropertyToBoolean("open.office.isEnable", "false")) {//鍚敤oepn office杞崲
        		officeManager = officeManagerQueue.take();
                inputFile = new File(input);
                outFile = new File(output);
                SpringMVCContextHolder.getSystemLogger().info("寮€濮嬭浆鎹㈡枃妗o細" + input + "=>" + output);
                OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
                converter.convert(inputFile, outFile); // 杞崲鏂囨。
            }else{
            	outFile = new File(AsposeUtil.OfficeToPdf(input, output,officeType));
        	}

        }catch (Exception e) {
            outFile = null;
            throw e;
        } finally {
            SpringMVCContextHolder.getSystemLogger().info("缁撴潫杞崲鏂囨。");
            if (officeManager != null) {
                try {
                    officeManagerQueue.put(officeManager);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return outFile;
    }
}