package com.qmth.jkserver.controller.system;

import com.qmth.jkserver.common.Constants;
import com.qmth.jkserver.constant.SystemConstant;
import com.qmth.jkserver.core.exception.JkServerException;
import com.qmth.jkserver.dto.RoomMonitorClientData;
import com.qmth.jkserver.dto.RoomMonitorClientLog;
import com.qmth.jkserver.model.Attachment;
import com.qmth.jkserver.params.RoomMonitorClientParam;
import com.qmth.jkserver.service.AttachmentService;
import com.qmth.jkserver.service.JkRoomMonitorClientDataService;
import com.qmth.jkserver.service.JkRoomMonitorClientLogService;
import com.qmth.jkserver.service.RoomMonitorClientService;
import com.qmth.jkserver.util.FileStoreUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.StringJoiner;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

/**
 * 监考端的日志下载 数据备份下载相关服务
 *
 * @author tianjun
 */
@RestController
@RequestMapping("/system/clientMonitor")
public class RoomMonitorClientController {

    @Resource
    @Lazy
    private RoomMonitorClientService roomMonitorClientService;

//    @Autowired
//    private MongoTemplate mongoTemplate;

    @Resource
    private FileStoreUtil fileStoreConfig;

    @Resource
    JkRoomMonitorClientLogService jkRoomMonitorClientLogService;

    @Resource
    AttachmentService attachmentService;

    @Resource
    JkRoomMonitorClientDataService jkRoomMonitorClientDataService;

    @RequestMapping("/queryLog")
    public Object pageQueryLog(HttpServletRequest request, HttpServletResponse response,
                               @RequestParam(required = false) String examCode,
                               @RequestParam(required = false) String placeCode,
                               @RequestParam(required = false) String placeName,
                               @RequestParam(required = false) String roomCode,
                               @RequestParam(required = false) Boolean upload,
                               @RequestParam(required = false) Integer pageNo,
                               @RequestParam(required = false) Integer pageSize
    ) {
        if (StringUtils.isEmpty(examCode)) {
            throw JkServerException.withFieldValidateError("考试识别码不能够是空的");
        }
        pageNo = pageNo == null ? 1 : pageNo;
        pageSize = pageSize == null ? Constants.DEFAULT_PAGE_SIZE : pageSize;
        RoomMonitorClientParam param = new RoomMonitorClientParam();
        param.setExamCode(examCode);
        param.setPlaceCode(placeCode);
        param.setPlaceName(placeName);
        param.setRoomCode(roomCode);
        param.setUpload(upload);
        Page<RoomMonitorClientLog> pages = roomMonitorClientService.pageQueryLog(param, pageNo, pageSize);
        return pages;
    }

    @RequestMapping("/queryData")
    public Object pageQueryData(HttpServletRequest request, HttpServletResponse response,
                                @RequestParam(required = false) String examCode,
                                @RequestParam(required = false) String placeCode,
                                @RequestParam(required = false) String placeName,
                                @RequestParam(required = false) String roomCode,
                                @RequestParam(required = false) Boolean upload,
                                @RequestParam(required = false) Integer pageNo,
                                @RequestParam(required = false) Integer pageSize
    ) {
        if (StringUtils.isEmpty(examCode)) {
            throw JkServerException.withFieldValidateError("考试识别码不能够是空的");
        }
        pageNo = pageNo == null ? 1 : pageNo;
        pageSize = pageSize == null ? Constants.DEFAULT_PAGE_SIZE : pageSize;
        RoomMonitorClientParam param = new RoomMonitorClientParam();
        param.setExamCode(examCode);
        param.setPlaceCode(placeCode);
        param.setPlaceName(placeName);
        param.setRoomCode(roomCode);
        param.setUpload(upload);
        Page<RoomMonitorClientData> pages = roomMonitorClientService.pageQueryData(param, pageNo, pageSize);
        return pages;
    }


    @RequestMapping("/downloadLog")
    public void downloadLog(HttpServletRequest request, HttpServletResponse response,
                            @RequestParam(required = false) String id
    ) throws ZipException, IOException {
        if (StringUtils.isEmpty(id)) {
            throw JkServerException.withFieldValidateError("ID不能够为空");
        }
//        Query query = new Query();
//        query.addCriteria(Criteria.where("id").is(new ObjectId(id)));
//        List<RoomMonitorClientLog> list = mongoTemplate.find(query, RoomMonitorClientLog.class);
        List<RoomMonitorClientLog> list = jkRoomMonitorClientLogService.listByIds(Arrays.asList(Long.parseLong(id)));
        if (list.size() == 0) {
            throw JkServerException.withMessage("数据记录不存在");
        }
        RoomMonitorClientLog roomMonitorClientLog = list.get(0);
        InputStream logStream = null;
        OutputStream outputStream = response.getOutputStream();
        ZipFile zipFile = null;
        try {
            //2020-12-19日加入阿里云下载
//            Attachment attachment = roomMonitorClientLog.getDecodeFile();
            Attachment attachment = attachmentService.getById(roomMonitorClientLog.getDecodeFileId());
            File file = null;
            if (fileStoreConfig.storageIsOss()) {
                StringJoiner stringJoiner = new StringJoiner("").add(fileStoreConfig.getStorageRoot())
                        .add(File.separator).add(attachment.getAccessUri());
                file = fileStoreConfig.ossDownload(stringJoiner.toString().replaceAll("\\\\", "/"), fileStoreConfig.getStorageRoot() + File.separator + attachment.getAccessUri(), fileStoreConfig.getStorageRoot());
            } else {
                file = new File(fileStoreConfig.getStorageRoot(), attachment.getAccessUri());
            }
            if (!file.exists()) {
                throw JkServerException.withMessage("已经解密的文件不存在," + file.getAbsolutePath());
            }
            zipFile = new ZipFile(file);
            ZipEntry zipEntry = new ZipEntry(roomMonitorClientLog.getName());
            logStream = zipFile.getInputStream(zipEntry);
            String fileName = roomMonitorClientLog.getName().replace("log/", "");
            fileName = URLEncoder.encode(fileName, SystemConstant.CHARSET_NAME);
            response.setCharacterEncoding(SystemConstant.CHARSET_NAME);
            response.addHeader("fileName", fileName);
            response.addHeader("fileSize", file.length() + "");
            response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
            IOUtils.copy(logStream, outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (zipFile != null) {
                IOUtils.closeQuietly(zipFile);
            }
            if (logStream != null) {
                IOUtils.closeQuietly(logStream);
            }
            if (outputStream != null) {
                IOUtils.closeQuietly(outputStream);
            }
        }

    }


    @RequestMapping("/downloadData")
    public void downloadData(HttpServletRequest request, HttpServletResponse response,
                             @RequestParam(required = false) String id
    ) throws ZipException, IOException {
        if (StringUtils.isEmpty(id)) {
            throw JkServerException.withFieldValidateError("ID不能够为空");
        }
//        Query query = new Query();
//        query.addCriteria(Criteria.where("id").is(new ObjectId(id)));
//        List<RoomMonitorClientData> list = mongoTemplate.find(query, RoomMonitorClientData.class);
        List<RoomMonitorClientData> list = jkRoomMonitorClientDataService.listByIds(Arrays.asList(Long.parseLong(id)));
        if (list.size() == 0) {
            throw JkServerException.withMessage("数据记录不存在");
        }
        RoomMonitorClientData roomMonitorClientData = list.get(0);
        InputStream logStream = null;
        OutputStream outputStream = response.getOutputStream();
        ZipFile zipFile = null;
        try {
//            Attachment attachment = roomMonitorClientData.getDecodeFile();
            Attachment attachment = attachmentService.getById(roomMonitorClientData.getDecodeFileId());
            //2020-12-19日加入阿里云下载
            File file = null;
            if (fileStoreConfig.storageIsOss()) {
                StringJoiner stringJoiner = new StringJoiner("").add(fileStoreConfig.getStorageRoot())
                        .add(File.separator).add(attachment.getAccessUri());
                file = fileStoreConfig.ossDownload(stringJoiner.toString().replaceAll("\\\\", "/"), fileStoreConfig.getStorageRoot() + File.separator + attachment.getAccessUri(), fileStoreConfig.getStorageRoot());
            } else {
                file = new File(fileStoreConfig.getStorageRoot(), attachment.getAccessUri());
            }
            if (!file.exists()) {
                throw JkServerException.withMessage("已经解密的文件不存在," + file.getAbsolutePath());
            }
            zipFile = new ZipFile(file);
            ZipEntry zipEntry = new ZipEntry(roomMonitorClientData.getName());
            logStream = zipFile.getInputStream(zipEntry);
            String fileName = roomMonitorClientData.getName();
            fileName = URLEncoder.encode(fileName, SystemConstant.CHARSET_NAME);
            response.setCharacterEncoding(SystemConstant.CHARSET_NAME);
            response.addHeader("fileName", fileName);
            response.addHeader("fileSize", file.length() + "");
            response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
            IOUtils.copy(logStream, outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (zipFile != null) {
                IOUtils.closeQuietly(zipFile);
            }
            if (logStream != null) {
                IOUtils.closeQuietly(logStream);
            }
            if (outputStream != null) {
                IOUtils.closeQuietly(outputStream);
            }
        }
    }
}
