package com.huatek.busi.service.impl.cac;

import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Service;
import com.google.common.collect.Maps;
import com.huatek.busi.common.CacMonitorTypeCode;
import com.huatek.busi.service.cac.CacEtlFactoryService;
import com.huatek.busi.service.cac.CacEtlService;
import com.huatek.torch.frame.exception.OwlException;
import com.huatek.torch.sql.beans.Pojo;

import lombok.extern.slf4j.Slf4j;

/**
 * CacEtlFactoryService实现类
 *
 * @author anker cheng
 *
 * @Date 2019年6月26日
 */
@Slf4j
@Component
@Service(interfaceClass = CacEtlFactoryService.class)
public class CacEtlFactoryServiceImpl<T extends Pojo> implements ApplicationContextAware, CacEtlFactoryService<T> {
    /** 实现类Map缓存 */
    private final Map<String, CacEtlService<T>> serviceImplMap = Maps.newConcurrentMap();

    @SuppressWarnings("unchecked")
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        applicationContext.getBeansOfType(CacEtlService.class).forEach((key, cacEtlService) -> {
            Class<?> persistentClass = cacEtlService.persistentClass();
            if (persistentClass != null) {
                log.debug("CAC报文处理实现类：{}", key);
                serviceImplMap.put(persistentClass.getName(), cacEtlService);
            }
        });
    }

    private final CacEtlService<T> serviceImpl(String key) {
        CacEtlService<T> service = serviceImplMap.get(key);
        if (service == null) {
            throw new OwlException("找不到Service实现类：" + key);
        }
        return service;
    }

    private final CacEtlService<T> serviceImpl(Map<String, Object> params) {
        String code = (String)params.get("cacMonitorTypeCode");
        CacMonitorTypeCode cacMonitorTypeCode = CacMonitorTypeCode.from(code);
        return serviceImpl(cacMonitorTypeCode.getTableClass().getName());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void doDispatch(T cacEntity) {
        serviceImpl(cacEntity.getClass().getName()).saveCACData(cacEntity);
    }

    @Override
    public Map<String, Object> findCACPageData(Map<String, Object> params) {
        return serviceImpl(params).findCACPageData(params);
    }



    @Override
    public Map<String, Object> exportCacMonitorData(Map<String, Object> params) {
        return serviceImpl(params).exportCacMonitorData(params);
    }
}
