package com.qmth.jkserver.core;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.model.ExamRoom;
import com.qmth.jkserver.service.JkExamRoomService;
import com.qmth.jkserver.service.JkRoomMonitorClientDataService;
import com.qmth.jkserver.service.JkRoomMonitorClientLogService;
import com.qmth.jkserver.util.FileStoreUtil;
import org.apache.commons.io.IOUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * 监考端服务
 *
 * @author tianjun
 */
@Service
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
public class RoomClientMonitorService {

//    @Autowired
//    private FileStoreConfig fileStoreConfig;

//    @Autowired
//    private MongoOperations mongoTemplate;

    //    @Resource
//    OssUtil ossUtil;
    @Resource
    FileStoreUtil fileStoreUtil;

    @Resource
    JkRoomMonitorClientLogService jkRoomMonitorClientLogService;

    @Resource
    JkRoomMonitorClientDataService jkRoomMonitorClientDataService;

    @Resource
    JkExamRoomService jkExamRoomService;

    @Async
    public void execute(Attachment decodeFile, String placeCode, String roomCode) throws Exception {
        //2020-12-19日加入阿里云下载
        InputStream inputStream = null;
        if (fileStoreUtil.storageIsOss()) {
            StringJoiner stringJoiner = new StringJoiner("").add(fileStoreUtil.getStorageRoot())
                    .add(File.separator).add(decodeFile.getAccessUri());
            byte[] data = fileStoreUtil.ossDownload(stringJoiner.toString(), fileStoreUtil.getStorageRoot());
            if (Objects.isNull(data)) {
                throw JkServerException.withMessage("解密之后的文件不存在,文件路径是:" + stringJoiner.toString());
            }
            inputStream = new ByteArrayInputStream(data);
        } else {
            File target = new File(fileStoreUtil.getStorageRoot(), decodeFile.getAccessUri());
            if (!target.exists()) {
                throw JkServerException.withMessage("解密之后的文件不存在,文件路径是:" + target.getAbsolutePath());
            }
            inputStream = new BufferedInputStream(new FileInputStream(target));
        }
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        ZipEntry zipEntry = null;
        //日志文件
        List<RoomMonitorClientLog> roomMonitorClientLogs = new ArrayList<RoomMonitorClientLog>();
        //监考端数据备份文件
        List<RoomMonitorClientData> roomMonitorClientdatas = new ArrayList<RoomMonitorClientData>();
        ExamRoom examRoom = findRoom(decodeFile.getExamCode(), placeCode, roomCode);
        try {
            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
                if (!zipEntry.isDirectory() && zipEntry.getName().endsWith(".xg")) {
                    RoomMonitorClientData data = new RoomMonitorClientData();
//                    data.setDecodeFile(decodeFile);
                    data.setId(SystemConstant.getDbUuid());
                    data.setDecodeFileId(decodeFile.getId());
                    data.setExamCode(decodeFile.getExamCode());
                    data.setName(zipEntry.getName());
                    data.setPlaceCode(placeCode);
                    data.setRoomCode(roomCode);
                    data.setPlaceName(examRoom.getPlaceName());
                    data.setRoomName(examRoom.getRoomName());
                    data.setTime(System.currentTimeMillis());
                    data.setSize((double) zipEntry.getSize());
                    data.setUpload(true);
                    roomMonitorClientdatas.add(data);
                }
                if (!zipEntry.isDirectory() && zipEntry.getName().indexOf("log/") > -1) {
                    RoomMonitorClientLog log = new RoomMonitorClientLog();
//                    log.setDecodeFile(decodeFile);
                    log.setId(SystemConstant.getDbUuid());
                    log.setDecodeFileId(decodeFile.getId());
                    log.setSize((double) zipEntry.getSize());
                    log.setExamCode(decodeFile.getExamCode());
                    log.setName(zipEntry.getName());
                    log.setPlaceCode(placeCode);
                    log.setRoomCode(roomCode);
                    log.setPlaceName(examRoom.getPlaceName());
                    log.setRoomName(examRoom.getRoomName());
                    log.setTime(System.currentTimeMillis());
                    log.setUpload(true);
                    roomMonitorClientLogs.add(log);
                }
            }
//            mongoTemplate.insert(roomMonitorClientdatas, RoomMonitorClientData.class);
//            mongoTemplate.insert(roomMonitorClientLogs, RoomMonitorClientLog.class);
            jkRoomMonitorClientDataService.saveOrUpdateBatch(roomMonitorClientdatas);
            jkRoomMonitorClientLogService.saveOrUpdateBatch(roomMonitorClientLogs);
        } finally {
            if (inputStream != null) {
                IOUtils.closeQuietly(inputStream);
            }
            if (zipInputStream != null) {
                IOUtils.closeQuietly(zipInputStream);
            }
        }
    }

    private ExamRoom findRoom(String examCode, String placeCode, String roomCode) {
//        Query query = new Query();
//        query.addCriteria(Criteria.where("examCode").is(examCode));
//        query.addCriteria(Criteria.where("placeCode").is(placeCode));
//        query.addCriteria(Criteria.where("roomCode").is(roomCode));
//        List<ExamRoom> examRooms = mongoTemplate.find(query, ExamRoom.class);
        QueryWrapper<ExamRoom> examRoomQueryWrapper = new QueryWrapper<>();
        examRoomQueryWrapper.lambda().eq(ExamRoom::getExamCode, examCode)
                .eq(ExamRoom::getPlaceCode, placeCode)
                .eq(ExamRoom::getRoomCode, roomCode);
        List<ExamRoom> examRooms = jkExamRoomService.list(examRoomQueryWrapper);
        return examRooms.size() > 0 ? examRooms.get(0) : null;
    }
}
