package cn.axzo.workflow.starter;

import cn.axzo.workflow.starter.common.enums.FailHandleTypeEnum;

import java.util.HashSet;
import java.util.Set;

import static cn.axzo.workflow.starter.common.enums.FailHandleTypeEnum.FAIL_OVER;

/**
 * 监听流程引擎广播的事件时一些行为控制
 * <pre>比如：
 * 1. 在遇到异常时的处理策略
 * 2. 过滤事件
 * </pre>
 *
 * @author wangli
 * @since 2024/6/4 14:14
 */
public class BroadcastListenerProperties {
    /**
     * 是否开启根据应用名过滤 MQ 事件
     * <p>
     * 如果为 true 时，在不对 {@link BroadcastListenerProperties#filterApplicationNames} 设任何值时，默认会将当前应用名加入进去
     */
    private Boolean enableFilterApplicationName = false;

    /**
     * 仅过滤这些应用名称创建的流程实例
     */
    private Set<String> filterApplicationNames = new HashSet<>();

    /**
     * 是否开启根据业务 ID 集合过滤 MQ 事件
     *
     * 业务 ID：从 OMS 平台中的“审批业务”查看，
     * <pre>
     * <img src="../../../../../imgs/business.png"/>
     * </pre>
     * 或者从“审批模板”中“业务 ID”进行查看
     * <pre>
     *     <img src="../../../../../imgs/process-model.png"/>
     * </pre>
     */
    private Boolean enableFilterDefinitionKey = false;

    /**
     * 过滤出 MQ 事件中包含这些业务 ID 的事件
     * <p>
     * 只有当 {@link  BroadcastListenerProperties#enableFilterDefinitionKey} 才生效
     * <p>
     * 注意: 如果 enableFilterDefinitionKey = true,但该属性集合为空, 将<strong color=orange>不会过滤</strong>任何消息
     */
    private Set<String> filterProcessDefinitionKeys = new HashSet<>();

    /**
     * 失败处理策略：
     * <pre>
     * 1、FAIL_OVER, 当前listener执行出错，在经历重试后，抛出异常，并将消息加入死信队列，然后继续往下执行(默认策略)
     * 2、FAIL_FAST, 快速失败，不管内部是什么异常类型，都将吞掉异常，正确结束，不会增加死信队列计数
     * <s>3、FAIL_BACK, 失败自动恢复，在后台记录失败的消息，并按照一定的策略后期再进行重试，</s>目前暂不支持
     * </pre>
     */
    private FailHandleTypeEnum failHandleType = FAIL_OVER;

    /**
     * 广播的 DLQ 监控
     */
    private Boolean monitorStatus = false;

    /**
     * 自动重试次数
     */
    private int numOfRetries = 3;

    /**
     * 初始等待时间,单位：毫秒
     */
    private int waitTimeInMs = 1500;

    /**
     * 重试累乘因子, 意味多次重试时，每次重试间隔为 waitTimeInMs * waitIncreaseFactor 毫秒
     */
    private int waitIncreaseFactor = 3;

    public Boolean getEnableFilterApplicationName() {
        return enableFilterApplicationName;
    }

    public void setEnableFilterApplicationName(Boolean enableFilterApplicationName) {
        this.enableFilterApplicationName = enableFilterApplicationName;
    }

    public Set<String> getFilterApplicationNames() {
        return filterApplicationNames;
    }

    public void setFilterApplicationNames(Set<String> filterApplicationNames) {
        this.filterApplicationNames = filterApplicationNames;
    }

    public Boolean getEnableFilterDefinitionKey() {
        return enableFilterDefinitionKey;
    }

    public void setEnableFilterDefinitionKey(Boolean enableFilterDefinitionKey) {
        this.enableFilterDefinitionKey = enableFilterDefinitionKey;
    }

    public Set<String> getFilterProcessDefinitionKeys() {
        return filterProcessDefinitionKeys;
    }

    public void setFilterProcessDefinitionKeys(Set<String> filterProcessDefinitionKeys) {
        this.filterProcessDefinitionKeys = filterProcessDefinitionKeys;
    }

    public FailHandleTypeEnum getFailHandleType() {
        return failHandleType;
    }

    public void setFailHandleType(FailHandleTypeEnum failHandleType) {
        this.failHandleType = failHandleType;
    }

    public Boolean getMonitorStatus() {
        return monitorStatus;
    }

    public void setMonitorStatus(Boolean monitorStatus) {
        this.monitorStatus = monitorStatus;
    }

    public int getNumOfRetries() {
        return numOfRetries;
    }

    public void setNumOfRetries(int numOfRetries) {
        this.numOfRetries = numOfRetries;
    }

    public int getWaitTimeInMs() {
        return waitTimeInMs;
    }

    public void setWaitTimeInMs(int waitTimeInMs) {
        this.waitTimeInMs = waitTimeInMs;
    }

    public int getWaitIncreaseFactor() {
        return waitIncreaseFactor;
    }

    public void setWaitIncreaseFactor(int waitIncreaseFactor) {
        this.waitIncreaseFactor = waitIncreaseFactor;
    }
}
