package com.wuban.tron.explore.fetch;

import com.wuban.tron.explore.handler.BlockDataHandler;
import com.wuban.tron.explore.handler.IBlockDataHandler;
import com.wuban.tron.explore.constant.Constant;
import com.wuban.tron.explore.domain.TronResponseData;
import com.wuban.tron.explore.service.LastBlockService;
import com.wuban.tron.explore.service.TronService;
import com.wuban.tron.explore.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 *  <core>区块数据抓取者服务接口方法实现类</core>
 *
 * @author sky
 * @date 2020/11/04
 */
@Slf4j
public class BlockDataFetcher<T> extends AbstractJob implements IBlockDataFetcher {

    private TronService tronService;

    private LastBlockService lastBlockService;

    private IBlockDataHandler handler;

    private StringRedisTemplate stringRedisTemplate;

    BlockDataFetcher(final BlockDataHandler handler) {
        this.handler = handler;
        tronService = SpringContextUtil.getBean(TronService.class);
        stringRedisTemplate = SpringContextUtil.getBean(StringRedisTemplate.class);
    }

    @Override
    public List fetch() {
        List<TronResponseData> dataList = new ArrayList<>();
        Long num = 0L;

        try {
           /* // 数据库获取区块高度
            num = this.lastBlockService.getForUpdate(1L);*/

            // Redis 获取区块高度
            String blockNumStr = this.stringRedisTemplate.opsForList().rightPop(Constant.BLOCK_NUM_LIST_KEY);
            if (!StringUtils.isEmpty(blockNumStr)) {
                num = Long.valueOf(blockNumStr);
                TronResponseData data = tronService.getBlockByNum(num);
                if (data != null) {
                    //log.info("已抓取数据区块高度 num:{}", num);
                    dataList.add(data);
                }
            }
        } catch (Exception e) {
            log.info(e.getMessage(), e);
        }

        return dataList;
    }

    @Override
    public void send(List list) throws InterruptedException {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        this.handler.receive(list);
    }

    @Override
    public boolean execute() {
        try {
            final List<T> list = fetch();
            if (CollectionUtils.isEmpty(list)) {
                return false;
            }
            send(list);
            return true;
        } catch (final Exception e) {
            log.error("fetch exception", e);
            return false;
        }
    }
}
