package com.skr.mdm.api.system.service.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.skr.mdm.api.system.service.SysChangeCertificateService;
import com.skr.mdm.bean.qo.controller.QueryObjectQO;
import com.skr.mdm.bean.so.SysChangeCertificateSO;
import com.skr.mdm.bean.vo.system.SysChangeCertificateVO;
import com.skr.mdm.constant.MinIoMessageConstants;
import com.skr.mdm.dao.DeviceEquipmentDao;
import com.skr.mdm.dao.SysChangeCertificateDao;
import com.skr.mdm.dao.SysChangeCertificateUserDao;
import com.skr.mdm.dto.LoginAdminDTO;
import com.skr.mdm.entity.SysChangeCertificateDO;
import com.skr.mdm.entity.SysChangeCertificateUserDO;
import com.skr.mdm.enums.LogAdminTypeEnum;
import com.skr.mdm.enums.ResultCodeEnum;
import com.skr.mdm.handle.IssuedUserHandler;
import com.skr.mdm.handle.LogAdminHandler;
import com.skr.mdm.manager.oss.MinIoManager;
import com.skr.mdm.result.ResponseResult;
import com.skr.mdm.util.PageUtil;
import com.skr.mdm.util.ReadFileUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * @ProjectName: mdm_new
 * @Package: com.skr.mdm.api.set.service.serviceImpl
 * @ClassName: SysChangeCertificateServiceImpl
 * @Author: Tty
 * @Description: 实现
 * @Date: 2020/11/30 10:38
 * @Version: 1.0
 */
@Service
public class SysChangeCertificateServiceImpl extends ServiceImpl<SysChangeCertificateDao, SysChangeCertificateDO> implements SysChangeCertificateService {
    @Autowired
    private SysChangeCertificateUserDao sysChangeCertificateUserDao;
    @Autowired
    private SysChangeCertificateDao sysChangeCertificateDao;
    @Autowired
    private MinIoManager minIoManager;
    @Autowired
    private DeviceEquipmentDao deviceEquipmentDao;
    @Autowired
    private IssuedUserHandler issuedUserHandler;
    @Autowired
    private LogAdminHandler logAdminHandler;

    @Override
    public ResponseResult readCerFile(MultipartFile file) throws Exception {
        Map<String, Object> fileInfoMap = ReadFileUtil.readCerFile(file.getInputStream());
        Set<String> keys = fileInfoMap.keySet();
        Iterator<String> iterator = keys.iterator();
        SysChangeCertificateVO sysChangeCertificateVO = new SysChangeCertificateVO();
        sysChangeCertificateVO.setCertificateName(file.getOriginalFilename());
        while (iterator.hasNext()) {
            String next = iterator.next();
            String value = fileInfoMap.get(next).toString();
            switch (next) {
                case "version":
                    sysChangeCertificateVO.setVersion(value);
                    break;
                case "subjectDN":
                    sysChangeCertificateVO.setSubjectDn(value);
                    break;
                case "issuerDN":
                    sysChangeCertificateVO.setIssuerDn(value);
                    break;
                case "notBefore":
                    sysChangeCertificateVO.setBeginTime((Date) fileInfoMap.get(next));
                    break;
                case "notAfter":
                    sysChangeCertificateVO.setEndTime((Date) fileInfoMap.get(next));
                    break;
                default:
                    break;
            }
        }
        return ResponseResult.success(sysChangeCertificateVO);
    }

    @Override
    public ResponseResult getCertificate(LoginAdminDTO admin) {
        SysChangeCertificateVO sysChangeCertificateVO = sysChangeCertificateDao.selectMaxChangCertificate(admin.getCompanyId());
        return ResponseResult.success(sysChangeCertificateVO);
    }

    @Override
    public ResponseResult queryList(QueryObjectQO queryObjectQO, LoginAdminDTO admin) {
        Integer companyId = admin.getCompanyId();
        queryObjectQO.setCompanyId(companyId);
        PageHelper.startPage(queryObjectQO.getPageNumber(), queryObjectQO.getPageSize());
        return ResponseResult.success(PageUtil.getPageResult(sysChangeCertificateUserDao.selectChangDeviceEquipmentById(queryObjectQO)));
    }

    @Override
    public ResponseResult addCertificate(LoginAdminDTO admin, MultipartFile file, SysChangeCertificateVO changeCertificateVO) throws Exception {
        //  证书id
        Integer id = changeCertificateVO.getId();

        Long count = new LambdaQueryChainWrapper<>(sysChangeCertificateDao)
                .eq(SysChangeCertificateDO::getCompanyId, admin.getCompanyId())
                .eq(StringUtils.isNotBlank(changeCertificateVO.getVersion()), SysChangeCertificateDO::getVersion, changeCertificateVO.getVersion())
                .eq(StringUtils.isNotBlank(changeCertificateVO.getSubjectDn()), SysChangeCertificateDO::getSubjectDn, changeCertificateVO.getSubjectDn())
                .eq(StringUtils.isNotBlank(changeCertificateVO.getIssuerDn()), SysChangeCertificateDO::getIssuerDn, changeCertificateVO.getIssuerDn())
                .eq(SysChangeCertificateDO::getIpName, changeCertificateVO.getIpName())
                .eq(SysChangeCertificateDO::getClientPort, changeCertificateVO.getClientPort())
                .eq(SysChangeCertificateDO::getSocketPort, changeCertificateVO.getSocketPort())
                .ne(null != id, SysChangeCertificateDO::getId, id)
                .count();
        if (count > 0) {
            return ResponseResult.failure(ResultCodeEnum.SERVER_MESSAGE_EXIST);
        }
        SysChangeCertificateDO sysChangeCertificateDO = new SysChangeCertificateDO();
        BeanUtils.copyProperties(changeCertificateVO, sysChangeCertificateDO);
        if (!file.isEmpty()) {
            String objectName = MinIoMessageConstants.MINIO_CERTIFICATE_OBJECT.concat("/")
                    .concat(changeCertificateVO.getCertificateName());
            String url = minIoManager.putObjectMinIo(admin.getCompanyId(), objectName, file, false);
            if (StringUtils.contains(url, "?")) {
                url = StringUtils.substringBefore(url, "?");
            }
            sysChangeCertificateDO.setDownloadUrl(url);
            sysChangeCertificateDO.setSourceName(objectName);
        }
        sysChangeCertificateDO.setCompanyId(admin.getCompanyId());
        sysChangeCertificateDao.insert(sysChangeCertificateDO);
        return ResponseResult.success();
    }

    @Override
    public ResponseResult sendCertificate(Integer changeCertificateId, LoginAdminDTO admin) {
        Integer companyId = admin.getCompanyId();
        List<Integer> deviceIdList = deviceEquipmentDao.listEquipmentIdByCompanyId(companyId);

        SysChangeCertificateDO sysChangeCertificateDO = sysChangeCertificateDao.selectById(changeCertificateId);
        if (CollectionUtils.isNotEmpty(deviceIdList)) {
            List<Integer> alreadyIdList = sysChangeCertificateUserDao.selectDeviceIdList(changeCertificateId);
            SysChangeCertificateSO sysChangeCertificateSO = new SysChangeCertificateSO();
            BeanUtils.copyProperties(sysChangeCertificateDO, sysChangeCertificateSO);
//            issuedUserHandler.insertSendMsg(deviceIdList, companyId,
//                    SendCmdConfigEnum.SYS_CERTIFICATE_INSTALL.getCmd(),
//                    JSONUtil.toJsonStr(sysChangeCertificateSO));
            if (CollectionUtils.isNotEmpty(alreadyIdList)) {
                deviceIdList.removeAll(alreadyIdList);
                new LambdaUpdateChainWrapper<>(sysChangeCertificateUserDao)
                        .set(SysChangeCertificateUserDO::getState, 0)
                        .in(SysChangeCertificateUserDO::getEquipmentId, alreadyIdList)
                        .eq(SysChangeCertificateUserDO::getChangeCertificateId, changeCertificateId)
                        .update();
            }
            if (CollectionUtils.isNotEmpty(deviceIdList)) {
                sysChangeCertificateUserDao.insertCertificateUserList(changeCertificateId, deviceIdList);
            }
        }
        new LambdaUpdateChainWrapper<>(sysChangeCertificateDao)
                .eq(SysChangeCertificateDO::getId, changeCertificateId)
                .set(SysChangeCertificateDO::getIssuedState, 1)
                .update();
        logAdminHandler.log(admin, LogAdminTypeEnum.OTHER_TYPE.getLogType(), "", "服务器变更", deviceIdList);
        return ResponseResult.success();
    }


}