package com.shkj.wcs.plc;

import HslCommunication.Core.Types.OperateResult;
import com.shkj.common.constant.RedisConstant;
import com.shkj.plc.sdk.device.PlcHelper;
import com.shkj.plc.sdk.device.PlcOperate;
import com.shkj.wcs.domain.WcsPlcConnect;
import com.shkj.wcs.service.IWcsPlcConnectService;
import com.shkj.wcs.vo.WcsPlcConnectVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component("PlcInit")
public class PlcInit implements ApplicationListener<ContextRefreshedEvent> {

    private PlcOperate plcOperate_dps;
    private PlcOperate plcOperate_dpj;

    @Resource
    IWcsPlcConnectService iWcsPlcConnectService;

    @Resource
    RedisTemplate redisTemplate;
    private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);


    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        //root application context 没有parent
        ApplicationContext context = event.getApplicationContext().getParent();
        if (context == null) {
            log.info("初始化连接对象");
            executorService.scheduleWithFixedDelay(
                    () -> reconnect(), 20, 20, TimeUnit.SECONDS
            );
            connect();
        }
    }

    public void connect() {
        //查询需要连接的PLC,初始化连接对象
        List<WcsPlcConnectVo> plcList = iWcsPlcConnectService.selectWcsPlcConnectList(new WcsPlcConnect().setIsActive("1"));
        if (plcList.size() == 0) {
            return;
        }
        //初始化系統时，把plc点位信息写入Redis
        redisTemplate.opsForValue().set(RedisConstant.redisPlcListConnect, plcList);

        for (WcsPlcConnectVo conn : plcList) {
            redisTemplate.opsForValue().set(RedisConstant.redisPlcConnect + conn.getDevCode(), conn);
            PlcHelper plc = new PlcHelper(conn.getPlcType(), conn.getPlcIp(), conn.getPlcFactory(), conn.getPort());
            if (conn.getPlcIp().contains("99.172")) {
                plcOperate_dpj = plc.getAutomation();
                if (plcOperate_dpj != null) {
                    OperateResult connect = plcOperate_dpj.connect();
                    if (connect.IsSuccess) {
                        log.info(conn.getPlcIp() + "dpj连接成功");
                    } else {
                        log.info(conn.getPlcIp() + "dpj连接失败");
                    }
                }
            }

            if (conn.getPlcIp().contains("99.151")) {
                plcOperate_dps = plc.getAutomation();
                if (plcOperate_dps != null) {
                    OperateResult connect = plcOperate_dps.connect();
                    if (connect.IsSuccess) {
                        log.info(conn.getPlcIp() + "dps连接成功");
                    } else {
                        log.info(conn.getPlcIp() + "dps连接失败");
                    }
                }
            }
        }
    }

    private void reconnect() {
        if (plcOperate_dps==null||!plcOperate_dps.isConnectd()) {
            connect();
        }
        if (plcOperate_dpj==null||!plcOperate_dpj.isConnectd()) {
            connect();
        }
    }

    public PlcOperate getPlcOperate_dps() {
        return plcOperate_dps;
    }

    public PlcOperate getPlcOperate_dpj() {
        return plcOperate_dpj;
    }


    public PlcOperate getPlcOperateByIp(String plcIp) {
        if (plcIp.contains("99.172")) {
            return plcOperate_dpj;
        }
        if (plcIp.contains("99.151")) {
            return plcOperate_dps;
        }
        return null;
    }
}
