package com.usoftchina.uas.office.service;

import com.alibaba.fastjson.JSON;
import com.usoftchina.uas.office.context.ContextHolder;
import com.usoftchina.uas.office.entity.DataCenter;
import com.usoftchina.uas.office.entity.Master;
import com.usoftchina.uas.office.event.DataCenterEvent;
import com.usoftchina.uas.office.event.MasterEvent;
import com.usoftchina.uas.office.jdbc.DataSourceHolder;
import com.usoftchina.uas.office.jdbc.DynamicDataSourceRegister;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.sql.SQLException;
import java.util.List;
import java.util.Objects;

/**
 * @author yingp
 * @date 2020/1/15
 */
@Service
public class MasterService extends AbstractService {

    private final Logger logger = LoggerFactory.getLogger(MasterService.class);

    private List<Master> mastersCache;

    @Autowired
    private DynamicDataSourceRegister dataSourceRegister;

    public Master findByName(String name) {
        if (null != mastersCache) {
            return mastersCache.stream().filter(m -> m.getMa_user().equalsIgnoreCase(name)).findFirst().orElse(null);
        }
        return null;
    }

    public synchronized void refreshMasters() throws SQLException {
        try {
            DataCenter dataCenter = DataCenter.INSTANCE;
            List<Master> masterList = null;
            if (null != dataCenter && null != dataCenter.getUsername() && null != dataCenter.getPassword() && null != dataCenter.getUrl()) {
                dataSourceRegister.register(dataCenter);
                DataSourceHolder.set(dataCenter);
                masterList = queryForBeanList("select * from master where nvl(ma_enable,0)=1 order by ma_id", Master.class);
                if (!CollectionUtils.isEmpty(masterList)) {
                    for (Master master : masterList) {
                        if (StringUtils.isEmpty(master.getMa_url())) {
                            master.setMa_url(dataCenter.url());
                        }
                        dataSourceRegister.register(master);
                    }
                }
            }
            if (!Objects.equals(mastersCache, masterList)) {
                if (null != masterList) {
                    for (Master master : masterList) {
                        ContextHolder.getApplicationContext().publishEvent(new MasterEvent(this, master));
                    }
                    logger.debug("masters refreshed, current masters: " + JSON.toJSONString(masterList));
                }
                this.mastersCache = masterList;
            }
        } finally {
            DataSourceHolder.clear();
        }
    }

    /**
     * 每5分钟刷新一次，防账套有变
     *
     * @throws Exception
     */
    @Scheduled(fixedDelay = 300000, initialDelay = 30000)
    public void scheduledRefresh() throws Exception {
        refreshMasters();
    }

    @Async
    @EventListener(DataCenterEvent.class)
    public void onDataCenterEvent(DataCenterEvent event) throws Exception {
        refreshMasters();
    }
}
