package com.qmth.jkserver.core.kj.validate;

import com.google.gson.reflect.TypeToken;
import com.qmth.jkserver.constant.SpringContextHolder;
import com.qmth.jkserver.constant.SystemConstant;
import com.qmth.jkserver.core.exception.JkServerException;
import com.qmth.jkserver.enums.ProgressType;
import com.qmth.jkserver.model.*;
import com.qmth.jkserver.service.AttachmentService;
import com.qmth.jkserver.service.ExamStudentAnswerService;
import com.qmth.jkserver.service.JkExamSolfegeRecordHistoryService;
import com.qmth.jkserver.service.JkExamSolfegeRecordService;
import com.qmth.jkserver.util.FileStoreUtil;
import com.qmth.jkserver.util.GsonUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

/**
 * 视唱答案数据校验以及存储
 *
 * @author tianjun
 */
public class StudentSolfegeKjValidateAndStore {

    private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(StudentSolfegeKjValidateAndStore.class);

    private ExamPlan examPlan;

    private ExamStudent examStudent;

    //考生单个答案文件 work目录
    private Attachment attachment;

    //考生单个答案文件 work目录
    private File file;

    public StudentSolfegeKjValidateAndStore(ExamPlan examPlan, ExamStudent examStudent, Attachment attachment) throws Exception {
        this.examPlan = examPlan;
        this.attachment = attachment;
        this.examStudent = examStudent;
        this.file = getFile(this.attachment);
    }

    public StudentSolfegeKjValidateAndStore(ExamPlan examPlan, ExamStudent examStudent, File file) {
        this.examPlan = examPlan;
        this.file = file;
        this.examStudent = examStudent;
    }

    protected File getFile(Attachment attachment) throws Exception {
        //2020-12-19日加入阿里云下载
        FileStoreUtil fileStoreConfig = SpringContextHolder.getBean(FileStoreUtil.class);
        File file = null;
        if (fileStoreConfig.workIsOss()) {
            StringJoiner stringJoiner = new StringJoiner("").add(fileStoreConfig.getWorkRoot())
                    .add(File.separator).add(attachment.getAccessUri());
            file = fileStoreConfig.ossDownload(stringJoiner.toString().replaceAll("\\\\", "/"), fileStoreConfig.getWorkRoot() + File.separator + attachment.getAccessUri(), fileStoreConfig.getWorkRoot());
        } else {
            file = new File(fileStoreConfig.getWorkRoot(), attachment.getAccessUri());
        }
        return file;
    }

    public void execute() throws Exception {
        FileStoreUtil fileStoreConfig = SpringContextHolder.getBean(FileStoreUtil.class);
        AttachmentService attachmentService = SpringContextHolder.getBean(AttachmentService.class);
        ExamStudentAnswerService examStudentAnswerService = SpringContextHolder.getBean(ExamStudentAnswerService.class);
        //校验zip包中的文件
        ZipFile zipFile = new ZipFile(file);
        InputStream inputStream = new FileInputStream(file);
        ZipInputStream zipInputStream = new ZipInputStream(inputStream, Charset.forName(SystemConstant.CHARSET_NAME));
        ZipEntry zipEntry = null;
        boolean ini = false;
        boolean record = false;
        //用于解析ini文件
        InputStream iniStream = null;
        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
            if (zipEntry.getName().endsWith("ini")) {
                ini = true;
                iniStream = zipFile.getInputStream(zipEntry);
            }
            if (zipEntry.getName().endsWith("mp3") || zipEntry.getName().endsWith("wav")) {
                record = true;
            }
        }
        if (!ini || !record) {
            throw JkServerException.MISSING_INI_OR_AUDIO_FILE;
        }
        //读取ini文件中的试卷包的名字
        BufferedReader bufferedReader = null;
        String paperName = null;
        try {
            bufferedReader = new BufferedReader(new InputStreamReader(iniStream, Charset.forName(SystemConstant.CHARSET_NAME)));
            String content = null;
            String paperNameLine = null;
            while ((content = bufferedReader.readLine()) != null) {
                if (content.indexOf("ItemID=") != -1) {
                    paperNameLine = content;
                    break;
                }
            }
            if (StringUtils.isEmpty(paperNameLine)) {
                throw JkServerException.SOLFEGE_ANSWER_ERROR;
            }
            String[] array = StringUtils.split(paperNameLine, "=");
            if (array.length != 2) {
                throw JkServerException.SOLFEGE_ANSWER_ERROR;
            }
            paperName = array[1];
        } finally {
            if (iniStream != null) {
                IOUtils.closeQuietly(iniStream);
            }
            if (bufferedReader != null) {
                bufferedReader.close();
            }
        }
        //考生答案文件存储路径选择 判断oss或者本地的文件系统
        Boolean a = fileStoreConfig.storageIsOss();
        if (a == null) {
            a = true;
        }
        String examCode = examPlan.getExamCode();
        //将校验通过的文件从临时目录转存到存储区存储
        Attachment answerFile = null;
        if (!a) {
            //存储到本地文件系统
            String path = examPlan.getExamType().name() + File.separator + examCode + File.separator + "kj";
            String accessUri = path + File.separator + attachment.getOriginalName();
            File root = new File(fileStoreConfig.getStorageRoot());
            File target = new File(root, accessUri);
            FileUtils.copyFile(file, target);
            answerFile = new Attachment();
            answerFile.setExamCode(examCode);
            answerFile.setExt(this.attachment.getExt());
            answerFile.setId(SystemConstant.getDbUuid());
            answerFile.setMd5(this.attachment.getMd5());
            answerFile.setName(this.attachment.getOriginalName());
            answerFile.setOriginalName(this.attachment.getName());
            answerFile.setPath(path);
            answerFile.setRelateId(this.attachment.getId());
            answerFile.setSize(this.attachment.getSize());
            answerFile.setTime(System.currentTimeMillis());
            answerFile.setType(this.attachment.getType());
            answerFile.setAccessUri(accessUri);
            attachmentService.saveOrUpdate(answerFile);
        } else {
            //存储到阿里云的OSS
            InputStream fileStream = null;
            try {
                fileStream = new FileInputStream(file);
                String key = examPlan.getExamType().name() + "/" + examCode + "/" + "kj" + "/" + attachment.getOriginalName();
//                answerFile = new Attachment();
//                OSSClient client = new OSSClient(aliYunOssConfig.getEndpoint(), aliYunOssConfig.getAccessKeyId(),
//                        aliYunOssConfig.getAccessKeySecret());
//                PutObjectResult result = client.putObject(aliYunOssConfig.getBucket(), key,
//                        fileStream);
//                client.shutdown();
//                if (StringUtils.isNotEmpty(result.getRequestId()) && result.getResponse() == null) {
//                    LOGGER.info("upload solfege answer to Aliyun OSS success key=:" + key);
//                } else {
//                    throw JkServerException.withFieldValidateError("");
//                }
                fileStoreConfig.ossUpload(key, fileStream, DigestUtils.md5Hex(new FileInputStream(file)), fileStoreConfig.getStorageRoot());
                answerFile = new Attachment();
                answerFile.setExamCode(examCode);
                answerFile.setExt(this.attachment.getExt());
                answerFile.setId(SystemConstant.getDbUuid());
                answerFile.setMd5(this.attachment.getMd5());
                answerFile.setName(this.attachment.getOriginalName());
                answerFile.setOriginalName(this.attachment.getName());
                answerFile.setRelateId(this.attachment.getId());
                answerFile.setSize(this.attachment.getSize());
                answerFile.setTime(System.currentTimeMillis());
                answerFile.setType(this.attachment.getType());
//                answerFile.setBucket(aliYunOssConfig.getBucket());
//                answerFile.setObjectKey(key);
                attachmentService.saveOrUpdate(answerFile);
            } finally {
                if (fileStream != null) {
                    IOUtils.closeQuietly(fileStream);
                }
            }
        }
//        List<ObjectId> OLD_ANSWER_LIST = new ArrayList<ObjectId>();
//        ObjectId oldId = examStudentAnswerService.findRecordIdByStudentId(examStudent.getId());
        List<Long> OLD_ANSWER_LIST = new ArrayList<Long>();
        Long oldId = examStudentAnswerService.findRecordIdByStudentId(examStudent.getId());
//        QueryWrapper<ExamStudentAnswer> examStudentAnswerQueryWrapper = new QueryWrapper<>();
//        examStudentAnswerQueryWrapper.lambda().eq(ExamStudentAnswer::getStudentId, examStudent.getId());
//        ExamStudentAnswer examStudentAnswer = examStudentAnswerService.getOne(examStudentAnswerQueryWrapper);
//        if (examStudentAnswer != null) {
//            OLD_ANSWER_LIST.add(examStudentAnswer.geta());
//        }
        ExamSolfegeRecord examSolfegeRecord = new ExamSolfegeRecord();
        examSolfegeRecord.setId(SystemConstant.getDbUuid());
        examSolfegeRecord.setExamCode(examCode);
        examSolfegeRecord.setStudentId(examStudent.getId());
        examSolfegeRecord.setAttachmentId(answerFile.getId());
        examSolfegeRecord.setTime(System.currentTimeMillis());
        examSolfegeRecord.setPaperName(paperName);
        examSolfegeRecord.setProgressType(ProgressType.REMOTE);
//        MongoTemplate mongoOperations = BeanFactory.getBean(MongoTemplate.class);
//        Object object = mongoOperations.getConverter().convertToMongoType(examSolfegeRecord);
//        DBObject dbObject = (DBObject) JSON.parse(object.toString());
//        dbObject.put("_class", ExamStudentAnswer.class.getName());
        List<ExamSolfegeRecord> list = new ArrayList<ExamSolfegeRecord>();
        list.add(examSolfegeRecord);
        //如果之前已经上传过则删除原来的答案
        JkExamSolfegeRecordService jkExamSolfegeRecordService = SpringContextHolder.getBean(JkExamSolfegeRecordService.class);
        if (OLD_ANSWER_LIST.size() > 0) {
//            DBObject delObject = new BasicDBObject("$in", OLD_ANSWER_LIST);
//            DBObject queryDel = new BasicDBObject("_id", delObject);
//            mongoOperations.getCollection("jk_exam_solfege_record").remove(queryDel);
            jkExamSolfegeRecordService.removeByIds(OLD_ANSWER_LIST);
        }
//        mongoOperations.getCollection("jk_exam_solfege_record").insert(list);
        jkExamSolfegeRecordService.saveOrUpdateBatch(list);
        JkExamSolfegeRecordHistoryService jkExamSolfegeRecordHistoryService = SpringContextHolder.getBean(JkExamSolfegeRecordHistoryService.class);
//        List<DBObject> hisList = list.stream().map(obj -> {
//            obj.put("_class", ExamSolfegeRecordHistory.class.getName());
//            return obj;
//        }).collect(Collectors.toList());
//        if (hisList.size() > 0) {
//            mongoOperations.getCollection("jk_exam_solfege_record_history").insert(list);
        List<ExamSolfegeRecordHistory> listHistory = GsonUtil.fromJson(GsonUtil.toJson(list), new TypeToken<List<ExamSolfegeRecordHistory>>() {
        }.getType());
        jkExamSolfegeRecordHistoryService.saveOrUpdateBatch(listHistory);
//        }
    }
}
