package cn.estsh.i3plus.ext.mes.apiservice.serviceimpl.base;

import cn.estsh.i3plus.ext.mes.api.base.IFileManageService;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.platform.bean.SysFile;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.fileservice.ImppFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * @author wangjie
 * @version 1.0
 * @date 2021/1/13 9:28
 **/
@Slf4j
@Service
public class FileManageService implements IFileManageService {

    @Autowired
    private ImppFileService imppFileService;

    @Override
    public SysFile uploadFile(MultipartFile file) {
        SysFile sysFile;
        try {
            log.info("文件大小{}", file.getBytes().length);
            sysFile = save2FastDfs(file);
            log.info("after save2FastDfs {}", sysFile);
        } catch (IOException e) {
            log.error("FastDFS上传文件出错：{}", e.getMessage() + "\r" + e.getStackTrace());
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode())
                    .setErrorDetail("上传文件至文件服务器出错了。信息为:%s", e.getMessage())
                    .build();
        }
        if (null == sysFile) {
            log.error("FastDFS上传文件出错");
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode())
                    .setErrorDetail("FastDFS上传文件出错")
                    .build();
        }
        if (StringUtils.isEmpty(sysFile.getFileTypeId())) {
            log.error("FastDFS上传文件出错：{}", "未在字典中定义该文件类型，无法上传成功，请先添加file_type字典");
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode())
                    .setErrorDetail("未在字典中定义该文件类型，无法上传成功，请先添加file_type字典")
                    .build();
        }
        return sysFile;
    }

    /**
     * 上传文件至FastDfs，目前私有，因为没有别的地方进行调用。
     *
     * @param multipartFile 文件
     * @return 带有URL地址的对象
     * @throws IOException
     */
    private SysFile save2FastDfs(MultipartFile multipartFile) throws IOException {
        SysFile sysFile = imppFileService.upload(multipartFile, CommonEnumUtil.SOFT_TYPE.MES.getValue());
        return sysFile;
    }

    @Override
    public void getFileByUrl(HttpServletResponse resp, String fileUrl) {
        InputStream inputStream = getInputStream(fileUrl);
        writeFile(resp, inputStream);
    }

    private static InputStream getInputStream(String urlPath) {
        InputStream inputStream = null;
        HttpURLConnection httpURLConnection;
        try {
            URL url = new URL(urlPath);
            httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setConnectTimeout(3000);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setRequestMethod("GET");
            int responseCode = httpURLConnection.getResponseCode();
            System.out.println("responseCode is:" + responseCode);
            if (responseCode == HttpURLConnection.HTTP_OK) {
                inputStream = httpURLConnection.getInputStream();
            } else {
                inputStream = httpURLConnection.getErrorStream();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return inputStream;
    }

    private static void writeFile(HttpServletResponse resp, InputStream inputStream) {
        OutputStream out = null;
        try {
            out = resp.getOutputStream();
            int len;
            byte[] b = new byte[1024];
            while ((len = inputStream.read(b)) != -1) {
                out.write(b, 0, len);
            }
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
