package com.xt.hb.data.core;

import java.util.concurrent.ScheduledExecutorService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xt.hb.data.service.FetchService;

/**
 * 抓取任务
 * 
 * @author 袁晓冬
 *
 */
public class FetchTask implements Runnable {
	private final static Logger logger = LoggerFactory.getLogger(FetchTask.class);
	private FetchService service;
	private ScheduledExecutorService executor;
	// 剩余重试次数
	private int count = 0;
	// 初始重试次数
	private final int initCount;

	public FetchTask(FetchService service, ScheduledExecutorService executor, int count) {
		initCount = count;
		this.service = service;
		this.executor = executor;
		this.count = count;
	}

	public <T extends FetchService> FetchTask(Class<T> serviceClazz, ScheduledExecutorService executor, int count) {
		try {
			this.service = serviceClazz.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
			logger.error("创建任务执行对象错误，类型：{}，错误消息：{}", serviceClazz.getName(), e.getMessage());
		}
		this.executor = executor;
		this.count = count;
		initCount = count;
	}

	@Override
	public void run() {
		logger.info("开始执行任务【{}】", service.getName());
		try {
			long start = System.currentTimeMillis();
			int count = service.doFetch();
			if (logger.isInfoEnabled()) {
				if (service.message() == null) {
					logger.info("【{}】耗时：{}s，成功执行抓取{}条数据", service.getName(),
							(System.currentTimeMillis() - start) / 1000.0, count);
				} else {
					logger.info("【{}】耗时：{}s，{}", service.getName(), (System.currentTimeMillis() - start) / 1000.0,
							service.message());

				}
			}
		}
		// 任务延时重新执行
		catch (TaskRedoException e) {
			if (count > 0) {
				executor.schedule(this, e.getDelay(), e.getUnit());
				count--;
				logger.error("执行任务【{}】失败:{}，延时 {} {} 执行，剩余重试次数：{}", service.getName(), e.getMessage(), e.getDelay(),
						e.getUnit(), count);
			} else {
				logger.error("执行任务【{}】失败:{}，服务接口：{}，重试结束", service.getName(), e.getMessage());
				// 重试结束，重置重试次数
				count = initCount;
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("执行任务【{}】失败，错误信息：{}", service.getName(), e.getMessage());
		}
	}
}
