package com.qmth.jkserver.controller.api;

import com.qmth.jkserver.constant.SystemConstant;
import com.qmth.jkserver.core.exception.JkServerException;
import com.qmth.jkserver.enums.ExamStatus;
import com.qmth.jkserver.model.AttachmentPhoto;
import com.qmth.jkserver.model.ExamPlan;
import com.qmth.jkserver.service.JkAttachmentPhotoService;
import com.qmth.jkserver.service.JkExamPlanService;
import com.qmth.jkserver.util.FileStoreUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLDecoder;
import java.util.StringJoiner;

/**
 * @author xf
 */
@RestController
@RequestMapping("/api/jkdevice")
public class FileUploadController implements Serializable {

    private static final long serialVersionUID = 227423597082641591L;

    private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadController.class);

    @Resource
    private FileStoreUtil fileStoreConfig;

    @Resource
    @Lazy
    private JkExamPlanService examPlanService;

    @Resource
    JkAttachmentPhotoService jkAttachmentPhotoService;

    /**
     * 考生抓拍头像图片上传
     *
     * @param request
     * @param file
     * @throws IOException
     */
    @RequestMapping(value = "/upload_catch_photo", method = RequestMethod.POST)
    public Object upload(HttpServletRequest request,
                         @RequestParam(required = false, value = "file") MultipartFile file) throws IOException {
        request.setCharacterEncoding(SystemConstant.CHARSET_NAME);
        String examCode = request.getHeader("examCode");
        String placeCode = request.getHeader("placeCode");
        String roomCode = request.getHeader("roomCode");
        String fileName = request.getHeader("fileName");
        String md5 = request.getHeader("md5");

        ExamPlan examPlan = examPlanService.findByExamCode(examCode);
        if (StringUtils.isEmpty(examCode) || examPlan == null) {
            throw JkServerException.EXAM_CODE_INVALID;
        }
        if (!ExamStatus.PUBLISHED.equals(examPlan.getExamStatus())) {
            throw JkServerException.EXAM_PLAN_UN_PUBLISHED;
        }

        if (file == null) {
            LOGGER.error("没有检测到文件实体");
            throw JkServerException.withMessage("没有检测到文件实体");
        } else {
            InputStream inputStream = null;
            OutputStream outputStream = null;
            try {
                // 创建随机文件夹
                File storeDir = new File(fileStoreConfig.getStorageRoot(), "photo");
                storeDir = new File(storeDir, examCode);
                if (!storeDir.exists()) {
                    storeDir.mkdirs();
                    if (!storeDir.exists()) {
                        throw JkServerException.withMessage("@@create dir failed:" + storeDir.getAbsolutePath());
                    }
                }
                if (StringUtils.isNotEmpty(fileName)) {
                    fileName = URLDecoder.decode(fileName, SystemConstant.CHARSET_NAME);
                }
                if (StringUtils.isEmpty(fileName)) {
                    fileName = file.getOriginalFilename();
                }
                File saveFile = new File(storeDir, fileName);
                LOGGER.info("@@target file:" + saveFile.getAbsolutePath());
                if (!saveFile.exists()) {
                    saveFile.createNewFile();
                }
                inputStream = file.getInputStream();
                outputStream = new FileOutputStream(saveFile);
                IOUtils.copy(inputStream, outputStream);
                // 存储文件
                AttachmentPhoto attachment = new AttachmentPhoto();
                attachment.setId(SystemConstant.getDbUuid());
                attachment.setExamCode(examCode);
                attachment.setPlaceCode(placeCode);
                attachment.setRoomCode(roomCode);
                attachment.setFileName(fileName);
                String mymd5 = DigestUtils.md5Hex(new FileInputStream(saveFile));
                if (StringUtils.isNotEmpty(md5)) {
                    if (!mymd5.equals(md5)) {
                        throw JkServerException.withMessage("文件MD5校验失败");
                    }
                }
                attachment.setSize((double) saveFile.length());
                attachment.setMd5(mymd5);
                attachment.setPath(saveFile.getAbsolutePath());
                attachment.setCreateTime(System.currentTimeMillis());
//				attachmentPhotoDao.save(attachment);
                jkAttachmentPhotoService.saveOrUpdate(attachment);
                IOUtils.closeQuietly(outputStream);
                IOUtils.closeQuietly(inputStream);
                //2020-12-19日加入上传到阿里云
                if (fileStoreConfig.storageIsOss()) {
                    StringJoiner stringJoiner = new StringJoiner("").add(fileStoreConfig.getStorageRoot()).add(File.separator).add("photo").add(File.separator).add(examCode).add(File.separator).add(fileName);
                    fileStoreConfig.ossUpload(stringJoiner.toString().replaceAll("\\\\", "/"), file.getInputStream(), mymd5, fileStoreConfig.getStorageRoot());
                    saveFile.delete();
                }
                System.out.println("upload file successfully:" + saveFile.getAbsolutePath());
                return true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (outputStream != null) {
                    IOUtils.closeQuietly(outputStream);
                }
                if (inputStream != null) {
                    IOUtils.closeQuietly(inputStream);
                }
            }
        }
        return true;
    }
}
