package cn.superdesk.uniorder.service.accounting.score.customer.strategy;

import cn.superdesk.uniorder.annotation.AccountingScoreCustomerStrategyType;
import cn.superdesk.uniorder.common.enums.common.CommonSourceFromEnum;
import cn.superdesk.uniorder.common.strategy.StrategyContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author xc
 * @description
 * @date 2022/5/20 15:45
 */
@Component
@Slf4j
public class AccountingScoreCustomerStrategyContext extends StrategyContext implements CommandLineRunner, ApplicationContextAware {

    private ApplicationContext context;
    private final ConcurrentHashMap<String, AccountingScoreCustomerStrategy> handlerMap = new ConcurrentHashMap<>();

    @Override
    public AccountingScoreCustomerStrategy getInstance(String type) {
        AccountingScoreCustomerStrategy strategy = handlerMap.get(type);
        //如果没有找到对应的策略，则默认返回结算中心策略
        if (strategy == null) {
            return handlerMap.get(CommonSourceFromEnum.结算中心.getSourceFromCode());
        }
        return strategy;
    }

    /**
     * 应用启动后会调用该方法
     * @param args
     * @throws Exception
     */
    @Override
    public void run(String... args) throws Exception {
        this.loadBean();
    }

    /**
     * 加载所有指定类型的bean
     */
    private void loadBean() {
        // 获取所有的实现了AccountingScoreCustomerStrategy的bean
        Map<String, AccountingScoreCustomerStrategy> beans = context.getBeansOfType(AccountingScoreCustomerStrategy.class);
        beans.forEach((handlerBeanName, handlerBean) -> {
            Class<?> clazz = handlerBean.getClass();
            AccountingScoreCustomerStrategyType annotation = clazz.getAnnotation(AccountingScoreCustomerStrategyType.class);
            String value = annotation.value();
            handlerMap.put(value, handlerBean);
        });
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }
}
