/**
* 文件：TableIndexServiceImpl.java
* 版本：1.0.0
* 日期：
* Copyright &reg; 
* All right reserved.
*/

package com.mortals.xhx.base.system.table.service.impl;

import com.mortals.framework.ap.GlobalSysInfo;
import com.mortals.framework.dao.ICRUDSubmeterDao;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.TableParam;
import com.mortals.framework.service.ITask;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.util.DateUtils;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.base.system.table.dao.TableIndexDao;
import com.mortals.xhx.base.system.table.model.TableIndexEntity;
import com.mortals.xhx.base.system.table.model.TableIndexQuery;
import com.mortals.xhx.base.system.table.service.TableIndexService;

import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>Title: 分表索引信息</p>
 * <p>Description: TableIndexServiceImpl service接口 </p>
 * <p>Copyright: Copyright &reg;  </p>
 * <p>Company: </p>
 * @author 
 * @version 1.0.0
 */
@Service("tableIndexService")
public class TableIndexServiceImpl extends AbstractCRUDServiceImpl<TableIndexDao,TableIndexEntity,Long> implements TableIndexService {

    /**
     * 查询最近1个月创建的表集合
     * @return
     */
    public Set<String> findLastMonthTables() {
        Set<String> retList = new HashSet<String>();
        try {
            TableIndexQuery params = new TableIndexQuery();
            params.setCreateTimeStart(DateUtils.addMonth(new Date(), -1, "yyyy-MM-dd"));
            List<TableIndexEntity> list = dao.getList(params);
            for (TableIndexEntity entity : list) {
                if (StringUtils.isNotEmpty(entity.getTableName())) {
                    retList.add(entity.getTableName());
                }
            }
        } catch (Exception e) {
            log.error("查询分表索引异常-->" + e.getMessage());
        }
        return retList;
    }

    @Override
    public Set<String> findPrevMonthTables() throws AppException {
        Set<String> retList = new HashSet<String>();
        try {
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.DAY_OF_MONTH, 1);
            cal.add(Calendar.MONTH, -1);
            String startTime = DateUtils.getDateTime(cal.getTime(), "yyyy-MM-dd");
            cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
            String endTime = DateUtils.getDateTime(cal.getTime(), "yyyy-MM-dd");
            TableIndexQuery params = new TableIndexQuery();
            params.setCreateTimeStart(startTime);
            params.setCreateTimeEnd(endTime);
            List<TableIndexEntity> list = dao.getList(params);
            for (TableIndexEntity entity : list) {
                if (StringUtils.isNotEmpty(entity.getTableName())) {
                    retList.add(entity.getTableName());
                }
            }
        } catch (Exception e) {
            log.error("查询分表索引异常-->" + e.getMessage());
        }
        return retList;
    }

    @Override
    public Set<String> findThreeMonthTables() throws AppException {
        Set<String> retList = new HashSet<String>();
        try {
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.DAY_OF_MONTH, 1);
            cal.add(Calendar.MONTH, -3);
            String startTime = DateUtils.getDateTime(cal.getTime(), "yyyy-MM-dd");
            TableIndexQuery params = new TableIndexQuery();
            params.setCreateTimeStart(startTime);
            List<TableIndexEntity> list = dao.getList(params);
            for (TableIndexEntity entity : list) {
                if (StringUtils.isNotEmpty(entity.getTableName())) {
                    retList.add(entity.getTableName());
                }
            }
        } catch (Exception e) {
            log.error("查询分表索引异常-->" + e.getMessage());
        }
        return retList;
    }

    @Override
    public int saveTableName(String tableName, String tableMark) throws AppException {
        TableIndexEntity table = new TableIndexEntity();
        table.setTableName(tableName);
        table.setTableMark(tableMark);
        table.setCreateTime(new Date());
        return dao.insert(table);
    }

    @Override
    public boolean createTable(ICRUDSubmeterDao submeterDao, TableParam param) {
        boolean ret = false;
        TableParam retParam = null;
        try {
            retParam = submeterDao.createTable(param);
            if (retParam != null && retParam.tableMap != null && retParam.tableMap.size() > 0) {
                log.info("创建表-->" + retParam.tableMap.keySet());
            }
        } catch (Exception e) {
            log.error("执行创建表任务异常-->" + submeterDao, e);
        }
        if (retParam != null && retParam.tableMap != null && retParam.tableMap.size() > 0) {
            TableIndexQuery condition = new TableIndexQuery();
            condition.setTableNameList(Arrays.asList(retParam.tableMap.keySet().toArray(new String[]{})));
            Set<String> tableRecords = this.find(condition, null).stream().map(t -> t.getTableName()).collect(Collectors.toSet());
            Date currDate = new Date();
            for (Map.Entry<String, String> ee : retParam.tableMap.entrySet()) {
                String tableName = ee.getKey();
                if(tableRecords.contains(tableName)) {
                    continue;
                }
                String tableMark = ee.getValue();
                try {
                    TableIndexEntity table = new TableIndexEntity();
                    table.setTableName(tableName);
                    table.setTableMark(tableMark);
                    table.setCreateTime(currDate);
                    dao.insert(table);
                    ret = true;
                } catch (Exception e) {
                    log.error("保存分表索引数据异常，原因：" + e.getMessage());
                }
            }
        }
        return ret;
    }

    @SuppressWarnings("rawtypes")
    private void createTable() throws AppException {
        log.info("执行表创建服务...");
        Map<String, ICRUDSubmeterDao> map = GlobalSysInfo.getBeansByType(ICRUDSubmeterDao.class);
        if (map == null || map.isEmpty()) {
            return;
        }
        Date currDate = new Date();
        //Set<String> existsTables = this.findLastMonthTables();
        Set<String> existsTables = this.findThreeMonthTables();
        TableParam param = new TableParam();
        param.unionTime = currDate;
        param.filterTables = existsTables;
        param.isCreateTable = true;
        for (Map.Entry<String, ICRUDSubmeterDao> entry : map.entrySet()) {
            this.createTable(entry.getValue(), param);
        }
        log.info("表创建完成！");
    }

    @Override
    public void excuteTask(ITask task) throws AppException {
        this.createTable();
    }

    @Override
    public void stopTask(ITask task) throws AppException {

    }

    @Override
    public void startService() throws AppException {
        this.createTable();
    }

    @Override
    public void stopService() throws AppException {

    }
	
}