package com.aizuda.easy.retry.template.datasource.access;

import com.aizuda.easy.retry.template.datasource.access.config.GroupConfigAccess;
import com.aizuda.easy.retry.template.datasource.access.config.NotifyConfigAccess;
import com.aizuda.easy.retry.template.datasource.access.config.SceneConfigAccess;
import com.aizuda.easy.retry.template.datasource.access.task.RetryDeadLetterTaskAccess;
import com.aizuda.easy.retry.template.datasource.access.task.RetryTaskAccess;
import com.aizuda.easy.retry.template.datasource.enums.OperationTypeEnum;
import com.aizuda.easy.retry.template.datasource.exception.EasyRetryDatasourceException;
import com.aizuda.easy.retry.template.datasource.persistence.po.*;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 数据处理模板类
 *
 * @author www.byteblogs.com
 * @date 2023-08-06 09:55:12
 * @since 2.2.0
 */
@Component
public class AccessTemplate {
    protected Map<String, Access> REGISTER_ACCESS = new HashMap<>();
    public AccessTemplate(List<Access> accesses) {

        for (Access access : accesses) {
            for (final OperationTypeEnum typeEnum : OperationTypeEnum.values()) {
                if (access.supports(typeEnum.name())) {
                    REGISTER_ACCESS.put(typeEnum.name(), access);
                    break;
                }
            }
        }
    }

    /**
     * 获取重试任务操作类
     *
     * @return {@link RetryTaskAccess} 重试任务操作类
     */
    public TaskAccess<RetryTask> getRetryTaskAccess() {
        return (TaskAccess<RetryTask>) Optional.ofNullable(REGISTER_ACCESS.get(OperationTypeEnum.RETRY_TASK.name()))
            .orElseThrow(() -> new EasyRetryDatasourceException("not supports operation type"));
    }

    /**
     * 获取死信任务操作类
     *
     * @return {@link RetryDeadLetterTaskAccess} 获取死信任务操作类
     */
    public TaskAccess<RetryDeadLetter> getRetryDeadLetterAccess() {
        return (TaskAccess<RetryDeadLetter>) Optional.ofNullable(
                REGISTER_ACCESS.get(OperationTypeEnum.RETRY_DEAD_LETTER.name()))
            .orElseThrow(() -> new EasyRetryDatasourceException("not supports operation type"));

    }

    /**
     * 获取场景配置操作类
     *
     * @return {@link SceneConfigAccess} 获取场景配置操作类
     */
    public ConfigAccess<SceneConfig> getSceneConfigAccess() {
        return (ConfigAccess<SceneConfig>) Optional.ofNullable(REGISTER_ACCESS.get(OperationTypeEnum.SCENE.name()))
            .orElseThrow(() -> new EasyRetryDatasourceException("not supports operation type"));

    }

    /**
     * 获取组配置操作类
     *
     * @return {@link GroupConfigAccess} 获取组配置操作类
     */
    public ConfigAccess<GroupConfig> getGroupConfigAccess() {
        return (ConfigAccess<GroupConfig>) Optional.ofNullable(REGISTER_ACCESS.get(OperationTypeEnum.GROUP.name()))
            .orElseThrow(() -> new EasyRetryDatasourceException("not supports operation type"));

    }

    /**
     * 获取通知配置操作类
     *
     * @return {@link NotifyConfigAccess} 获取通知配置操作类
     */
    public ConfigAccess<NotifyConfig> getNotifyConfigAccess() {
        return (ConfigAccess<NotifyConfig>) Optional.ofNullable(REGISTER_ACCESS.get(OperationTypeEnum.NOTIFY.name()))
            .orElseThrow(() -> new EasyRetryDatasourceException("not supports operation type"));

    }

}
