package com.dxhy.erp.service.impl;

import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.erp.dao.SysDeptDao;
import com.dxhy.erp.entity.InvoiceElectron;
import com.dxhy.erp.service.CheckTaskService;
import com.dxhy.erp.service.QsCheckTaskService;
import com.dxhy.erp.task.QsCheckThread;

import lombok.extern.slf4j.Slf4j;

/**
 * @author dxhy
 */
@Service("checkTaskService")
@Slf4j
public class CheckTaskServiceImpl implements CheckTaskService {

    @Resource
    private SysDeptDao sysDeptDao;
    @Resource
    private QsCheckTaskService qsCheckTaskService;

    public void checkInvoice() {
        log.info("YL发票查验执行开始");
        try {
            // 查询需要补全明细的数据
            // 查询需要遍历的数据库
            // 查询数据库 遍历数据源
            DynamicContextHolder.push(DbConstant.BASICS_READ);
            List<String> dbList = sysDeptDao.getDbSource();
            for (String db : dbList) {
                DynamicContextHolder.push(db + DbConstant.BUSINESS_READ);
                List<InvoiceElectron> electornList = qsCheckTaskService.selectElectronToCheck();

                ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 15, 5, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<>(electornList.size()), new ThreadPoolExecutor.CallerRunsPolicy());

                for (InvoiceElectron invoiceElectron : electornList) {
                    Thread thread = new QsCheckThread(qsCheckTaskService, db, invoiceElectron);
                    // 将线程放入池中进行执行
                    if (!threadPoolExecutor.isShutdown()) {
                        threadPoolExecutor.execute(thread);
                    }
                }
                threadPoolExecutor.shutdown();
                threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("定时验证失败:{}", e.getMessage());
        }
        log.info("---------------发票查验执行结束-------------------");
    }
}
