package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.jx;

import cn.estsh.i3plus.ext.mes.pcn.api.busi.jx.IJxPlcExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.busi.dispatch.cachedispatch.WorkCellDataCacheDispatch;
import cn.estsh.i3plus.platform.plugin.opc.iservice.IOpcUAService;
import cn.estsh.i3plus.platform.plugin.opc.service.OpcUAService;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.hardswitch.bean.OpcUAParam;
import cn.estsh.i3plus.pojo.mes.bean.MesObjectCfg;
import cn.estsh.i3plus.pojo.mes.bean.MesPlc;
import cn.estsh.i3plus.pojo.mes.repository.MesObjectCfgRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesPlcRepository;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.MessageFormat;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: wangjie
 * @CreateDate: 2021/01/18 11:41 上午
 * @Description:
 **/
@Slf4j
@Service
public class JxPlcExtService implements IJxPlcExtService {

    @Autowired
    private MesPlcRepository plcRepository;

    @Autowired
    private MesObjectCfgRepository objectCfgRepository;

    @Override
    public MesPlc getPlcDb(String organizeCode, String plcCode) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(plcCode)) return null;
        return plcRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.PLC_CODE},
                new Object[]{organizeCode, CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), plcCode});
    }

    @Override
    public List<MesPlc> getPlcDbList(String organizeCode, String workCenterCode, String workCellCode) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode) || StringUtils.isEmpty(workCellCode)) return null;
        return plcRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.WORK_CENTER_CODE, MesPcnExtConstWords.WORK_CELL_CODE},
                new Object[]{organizeCode, CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), workCenterCode, workCellCode});
    }

    @Override
    public Object doReadOpcParamValue(MesPlc plc) {
        IOpcUAService opcService = new OpcUAService();
        String tagAddress = MessageFormat.format("{0}.{1}.{2}", plc.getChannel(), plc.getDevice(), plc.getTagAddress());
        OpcUAParam opcParam = new OpcUAParam();
        opcParam.setServerUrl(plc.getOpcUrl());
        opcParam.setTagAddress(tagAddress);
        opcParam.setNamespaceIndex(plc.getNameSpaceIndex());
        opcParam.setTagValueType(plc.getDataType());
        Object result = opcService.getOpcParamValue(opcParam);
        return result;
    }

    @Override
    public Boolean doWriteOpcParamValue(MesPlc plc, String value) {
        IOpcUAService opcService = new OpcUAService();
        String tagAddress = MessageFormat.format("{0}.{1}.{2}", plc.getChannel(), plc.getDevice(), plc.getTagAddress());
        OpcUAParam opcParam = new OpcUAParam();
        opcParam.setServerUrl(plc.getOpcUrl());
        opcParam.setTagAddress(tagAddress);
        opcParam.setNamespaceIndex(plc.getNameSpaceIndex());
        opcParam.setTagValueType(plc.getDataType());
        opcParam.setTagValue(value);
        Boolean result = opcService.editOpcParamValue(opcParam);
        return result;
    }

    @Override
    public MesPlc getPlcData(String organizeCode, String key, String plcCode) {
        String value = getCachedData(key, plcCode);
        if (!StringUtils.isEmpty(value)) return JSONObject.parseObject(value, MesPlc.class);
        MesPlc plc = getPlcDb(organizeCode, plcCode);
        if (null == plc) plc = new MesPlc();
        doCacheData(organizeCode, key, plcCode, JSONObject.toJSONString(plc));
        return plc;
    }

    @Override
    public String getCachedData(String key, String item) {
        return new WorkCellDataCacheDispatch.builder().key(key).item(item).build().get().getValue();
    }

    @Override
    public void doCacheData(String organizeCode, String key, String item, String data) {
        new WorkCellDataCacheDispatch.builder().key(key).item(item).value(data).timeSecond(MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue()).org(organizeCode).build().save();
    }

    @Override
    public List<MesObjectCfg> getObjectCfgDbList(String organizeCode, List<String> plcCodeList) {
        if (StringUtils.isEmpty(organizeCode)) return null;
        List<MesObjectCfg> objectCfgDbList = objectCfgRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.IS_DELETED},
                new Object[]{organizeCode, CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()});
        objectCfgDbList = CollectionUtils.isEmpty(objectCfgDbList) ? null :
                objectCfgDbList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPlcCode()) && plcCodeList.contains(o.getPlcCode()))).collect(Collectors.toList());
        return objectCfgDbList;
    }
}