package org.springblade.common.notify.message;

import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import java.io.Serializable;
import java.util.Properties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;

/**
 * 对象池工厂
 *
 * @author caiyihua
 */
@Slf4j
public class ProducerPooledObjectFactory implements PooledObjectFactory<Producer>, Serializable {
    Properties properties;

    public ProducerPooledObjectFactory(Properties properties) {
        this.properties = properties;
    }

    @Override
    public PooledObject<Producer> makeObject() throws Exception {
        Producer producer = ONSFactory.createProducer(properties);
        Object producerId = properties.get(PropertyKeyConst.GROUP_ID);
        if (producerId == null) {
            producerId = properties.get(PropertyKeyConst.ProducerId);
        }
        log.info("ALi Producer {} for the producer ID {} started!", producer.toString(), producerId);
        // 在发送消息前，必须调用 start 方法来启动 Producer，只需调用一次即可。
        producer.start();
        return new DefaultPooledObject(producer);
    }

    @Override
    public void destroyObject(PooledObject<Producer> p) throws Exception {
        Producer o = p.getObject();
        o.shutdown();
        Object producerId = properties.get(PropertyKeyConst.GROUP_ID);
        if (producerId == null) {
            producerId = properties.get(PropertyKeyConst.ProducerId);
        }
        log.info("ALi Producer {} for the producer ID {} has been shutdown!", o.toString(), producerId);
        o = null;
    }

    @Override
    public boolean validateObject(PooledObject<Producer> p) {
        Producer o = p.getObject();
        return o.isStarted();
    }

    @Override
    public void activateObject(PooledObject<Producer> p) throws Exception {

    }

    @Override
    public void passivateObject(PooledObject<Producer> p) throws Exception {

    }
}
