package com.tax.token.job;

import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.dataflow.DataflowJob;
import com.google.common.base.Stopwatch;
import com.tax.token.model.TkToken;
import com.yxcheng.token.utils.UUIDGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

@Slf4j
@Component
public class SynGetTokenJob implements DataflowJob<TkToken> {

    /**
     * limit query default
     */
    public static final int LIMIT_QUERY_DEFAULT = 100;

    /**
     * invoke thread threshold
     */
    public static final int INVOKE_THREAD_THRESHOLD = 50;

    @Autowired
    private SynGetTokenTask synGetTokenTask;

    @Override
    public List<TkToken> fetchData(ShardingContext shardingContext) {
        log.info("token-job fetch data is start");
        int limit = this.getLimit(shardingContext);
        int totalCount = shardingContext.getShardingTotalCount();
        int item = shardingContext.getShardingItem();
        Stopwatch stopwatch = Stopwatch.createStarted();
        List<TkToken> tkTokenList = synGetTokenTask.getTokenList(totalCount, item, limit);
        stopwatch.stop();
        log.info("token-job totalCount:{}, item:{}, limit:{}, fetch token list size: {}, elapsed: {} ms", totalCount, item, limit, tkTokenList.size(), stopwatch.elapsed(TimeUnit.MILLISECONDS));
        return tkTokenList;
    }

    @Override
    public void processData(ShardingContext shardingContext, List<TkToken> list) {
        String uuidFlag = UUIDGenerator.generate();
        log.info("{} token-job process data is start", uuidFlag);
        Stopwatch stopwatch = Stopwatch.createStarted();
        int limit = this.getLimit(shardingContext);
        if (limit > INVOKE_THREAD_THRESHOLD) {
            log.info("{} async execute job", uuidFlag);
            synGetTokenTask.asyncRunToken(uuidFlag, list);
        } else {
            log.info("{} sync execute job", uuidFlag);
            synGetTokenTask.syncRunToken(uuidFlag, list);
        }
        stopwatch.stop();
            log.info("{} token-job process token list size: {} finished, elapsed: {} ms", uuidFlag, list.size(), stopwatch.elapsed(TimeUnit.MILLISECONDS));
    }

    /**
     * get query result limit.
     * @param shardingContext
     * @return
     */
    private int getLimit(ShardingContext shardingContext) {
        int limit = LIMIT_QUERY_DEFAULT;
        String jobParameter = shardingContext.getJobParameter();
        if (StringUtils.isNotBlank(jobParameter)) {
            limit = Integer.valueOf(jobParameter);
        }
        return limit;
    }
}
