package cd.casic.module.machine.service.impl;

import cd.casic.framework.commons.pojo.CommonResult;
import cd.casic.framework.commons.pojo.PageResult;
import cd.casic.framework.commons.util.object.BeanUtils;
import cd.casic.module.machine.controller.vo.SecretKeyVO;
import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
import cd.casic.module.machine.dal.dataobject.SecretKeyDO;
import cd.casic.module.machine.dal.mysql.SecretKeyMapper;
import cd.casic.module.machine.service.MachineInfoService;
import cd.casic.module.machine.service.SecretKeyService;
import cd.casic.module.machine.utils.CryptogramUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.annotations.VisibleForTesting;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.script.ScriptException;
import java.util.List;
import java.util.Objects;

import static cd.casic.framework.commons.exception.util.ServiceExceptionUtil.exception;
import static cd.casic.module.machine.contants.MachineErrorCodeConstants.*;

/**
 * 密钥服务实现类
 */
@Service("secretKeyService")
public class SecretKeyServiceImpl implements SecretKeyService {

    @Resource
    private MachineInfoService machineInfoService;

    @Resource
    private SecretKeyMapper secretKeyMapper;

    @Override
    public SecretKeyVO getSecretKey(Long id) {
        SecretKeyDO secretKeyDO = validateSecretKeyExists(id);
        return BeanUtils.toBean(secretKeyDO, SecretKeyVO.class);
    }

    @Override
    public List<MachineInfoDO> getBindMachine(Long secretKeyId) {
        return machineInfoService.selectBindMachineBySecretKey(secretKeyId);
    }

    @Override
    public String getPublicKeyContent(Long secretKeyId) {
        return secretKeyMapper.selectById(secretKeyId).getPublicKey();
    }

    @Override
    public Long createSecretKey(SecretKeyVO secretKeyVO) {
        validateSecretKeyAdd(secretKeyVO);
        SecretKeyDO secretKeyDO = BeanUtils.toBean(secretKeyVO, SecretKeyDO.class);
        //密码加密
        secretKeyDO.setPassword(CryptogramUtil.doEncrypt(secretKeyVO.getPassword()));
        //公私钥加密
        secretKeyDO.setPublicKey(CryptogramUtil.doEncrypt(secretKeyVO.getPublicKey()));
        secretKeyDO.setPrivateKey(CryptogramUtil.doEncrypt(secretKeyVO.getPrivateKey()));
        secretKeyMapper.insert(secretKeyDO);
        return secretKeyDO.getId();
    }

    @Override
    public void updateSecretKey(SecretKeyVO secretKeyVO) {
        SecretKeyDO secretKeyDO = validateSecretKeyExists(secretKeyVO.getId());
        BeanUtils.copyProperties(secretKeyVO, secretKeyDO);
        secretKeyMapper.updateById(secretKeyDO);
    }

    @Override
    @Transactional
    public void deleteSecretKeyList(List<Long> ids) {
        SecretKeyVO secretKeyVO = new SecretKeyVO()
            .setMachineInfoIds(ids)
            .setEnableBind(false);
        machineInfoService.bindingSecretKey(secretKeyVO);
        secretKeyMapper.deleteBatchIds(ids);
    }

    @Override
    public PageResult<SecretKeyDO> getSecretKeyPage(SecretKeyVO secretKeyVO) {
        return secretKeyMapper.selectPage(secretKeyVO, new LambdaQueryWrapper<SecretKeyDO>()
                .like(Objects.nonNull(secretKeyVO.getName()), SecretKeyDO::getName, secretKeyVO.getName())
                .like(Objects.nonNull(secretKeyVO.getDescription()), SecretKeyDO::getDescription, secretKeyVO.getDescription()));
    }

    @VisibleForTesting
    void validateSecretKeyAdd(SecretKeyVO secretKeyVO) {
        if (secretKeyVO == null) {
            throw exception(SECRET_KEY_NULL);
        }
    }

    @VisibleForTesting
    SecretKeyDO validateSecretKeyExists(Long id) {
        if (id == null) {
            throw exception(SECRET_KEY_NOT_EXISTS);
        }
        SecretKeyDO secretKeyDO = secretKeyMapper.selectById(id);
        if (secretKeyDO == null) {
            throw exception(SECRET_KEY_NOT_EXISTS);
        }
        return secretKeyDO;
    }
    @Override
    public Integer deleteById(Long id){
        return secretKeyMapper.deleteById(id);
    }
}
