package com.xhpc.pp.logic;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.xhpc.common.enums.StationDeviceEnum;
import com.xhpc.pp.domain.XhpcDeviceMessage;
import com.xhpc.pp.mapper.XhpcDeviceMessageMapper;
import com.xhpc.pp.tx.ServiceParameter;
import com.xhpc.pp.tx.ServiceResult;
import com.xhpc.pp.tx.logic.ServiceLogic;
import com.xhpc.pp.utils.HexUtils;
import com.xhpc.pp.utils.security.CRCCalculator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;

import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS;
import static com.xhpc.common.data.redis.StaticBeanUtil.seqHex;

@Lazy
@Component("RemoteUpgradeDataLogic")
public class RemoteUpgradeDataLogic  implements ServiceLogic {

    private static final Logger log = LoggerFactory.getLogger(RemoteUpgradeDataLogic.class);

    @Resource
    XhpcDeviceMessageMapper deviceMessageMapper;


    @Override
    public ServiceResult service(ServiceParameter sp) throws Exception {
        Map<String, Object> req = sp.getParameters();
        String pileNo = (String) req.get("pileNo");
        Map<String, Object> cachePile = REDIS.getCacheMap("pile:".concat(pileNo));
        if(!"已注册".equals(cachePile.get("status").toString())){
            ObjectMapper mapper = new ObjectMapper();
            ObjectNode json = mapper.createObjectNode();
            json.put("error", "桩未注册");
            return new ServiceResult(null, ServiceResult.FAIL, json);
        }

        String resultStr = translate(pileNo, "0", 0L, "0", "0", "0", 2);

        String remark = "充电桩主动下发远程更新";
        XhpcDeviceMessage deviceMessage = new XhpcDeviceMessage();
        deviceMessage.setType(StationDeviceEnum.PILE.getCode());
        deviceMessage.setSerialNumber(sp.getPileNo());
        deviceMessage.setRemark(remark);
        deviceMessage.setStatus(0);
        deviceMessage.setContent(resultStr);
        deviceMessageMapper.insertByDomain(deviceMessage);
        return new ServiceResult(HexUtils.toBytes(resultStr), ServiceResult.OK);
    }

    public static String translate(String pileNo, String remoteHost, Long port, String ftpUserName, String ftpPassword, String upgradeUrl, int runFlag) {

        String skey = "pile:".concat(pileNo).concat(".seqhex");
        Map<String, Object> cachePile = REDIS.getCacheMap("pile:".concat(pileNo));
        Long pileType = Long.parseLong(cachePile.get("equipmentType") + "");    // 桩型号（01-直流, 02-交流）
        Long pilePower = new Double((double)cachePile.get("power")).longValue();           // 桩功率

        String resultStr = "6862".concat(seqHex(skey)).concat("0094")
                .concat(pileNo).concat(String.format("%02X", pileType)).concat(String.format("%04X", pilePower))
                .concat(stringToAscii(remoteHost, 16)).concat(String.format("%02X", port))
                .concat(stringToAscii(ftpUserName, 16)).concat(stringToAscii(ftpPassword, 16))
                .concat(stringToAscii(upgradeUrl, 32)).concat(String.format("%02x", runFlag)).concat("01");

        resultStr = resultStr.concat(CRCCalculator.calcCrc(resultStr));
        return resultStr;
    }

    private static String stringToAscii(String value, int length){
        StringBuilder sb = new StringBuilder();
        char[] chars = value.toCharArray();
        for (char aChar : chars) {
            sb.append((int) aChar);
        }

        String resultStr = sb.toString();
        if (resultStr.length() < length){
            resultStr = String.format("%"+ length+"s", resultStr).replaceAll(" ", "0");
        }

        return resultStr;
    }
}
