package com.xzzn.common.core.modbus;


import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.ip.IpParameters;

import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

public class PooledModbusMasterFactory extends BasePooledObjectFactory<ModbusMaster> {

    private final String host;
    private final int port;

    public PooledModbusMasterFactory(String host, int port) {
        this.host = host;
        this.port = port;
    }

    @Override
    public ModbusMaster create() throws Exception {
        IpParameters params = new IpParameters();
        params.setHost(this.host);
        params.setPort(this.port);
        params.setEncapsulated(false);

        ModbusMaster master = new ModbusFactory().createTcpMaster(params, true);
        master.init();
        return master;
    }

    @Override
    public PooledObject<ModbusMaster> wrap(ModbusMaster master) {
        return new DefaultPooledObject<>(master);
    }

    @Override
    public void destroyObject(PooledObject<ModbusMaster> p) throws Exception {
        if (p.getObject() != null) {
            p.getObject().destroy();
        }
        super.destroyObject(p);
    }

    @Override
    public boolean validateObject(PooledObject<ModbusMaster> p) {
        // testConnectivity() 方法在 modbus4j 中不存在。
        // 一个真正的验证需要执行一次读操作，但这需要 slaveId，而工厂是通用的，不知道 slaveId。
        // 因此，我们使用一个较弱的验证，只检查 master 对象是否已初始化。
        // 这无法检测到被远程设备断开的连接，错误将在实际读取操作中被捕获。
        if (p.getObject() == null) {
            return false;
        }
        return p.getObject().isInitialized();
    }
}
