package cn.superdesk.uniorder.common.queue.block;

import lombok.extern.slf4j.Slf4j;

import java.lang.ref.WeakReference;
import java.util.concurrent.PriorityBlockingQueue;


/**
 * @Description: 任务基本定义 基类
 * 先不用lombok实现
 * 两个模式
 * @Author: linjinyu
 * @CreateDate: 2021/9/10 下午1:53
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/9/10 下午1:53
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
public class BaseTask implements TaskInterface {

	private final String TAG = getClass().getSimpleName();

	// 默认优先级
	private   TaskPriorityEnum              mTaskPriority = TaskPriorityEnum.MIDDLE;
	// 入队次序
	private   int                           mSequence;
	// 标志任务状态,是否仍在展示
	private   Boolean                       mTaskStatus   = false;
	// 阻塞队列
	protected WeakReference<BlockTaskQueue> blockTaskQueueWeakRef;
	// 任务执行时间
	protected int                           duration      = 0;

	protected String taskParamsJson;

	// 此队列用来实现任务时间不确定的队列阻塞功能
	// PriorityBlockingQueue 是一个支持优先级的无界阻塞队列
	private PriorityBlockingQueue<Integer> blockQueue;

	// 构造函数
	public BaseTask() {

		// 放置任务的队列
		blockTaskQueueWeakRef = new WeakReference<>(BlockTaskQueue.getInstance());
		// 处理任务的队列
		blockQueue = new PriorityBlockingQueue<>();
	}

	/**
	 * 入队实现
	 */
	@Override
	public void enqueue() {
		TaskScheduler.getInstance().enqueue(this);
	}

	/**
	 * 执行任务方法,此时标记为设为true,并且将当前任务记录下来
	 */
	@Override
	public void doTask() {
		mTaskStatus = true;
		CurrentRunningTask.setCurrentShowingTask(this);
	}

	/**
	 * 任务执行完成,改变标记位,将任务在队列中移除,并且把记录清除
	 */
	@Override
	public void finishTask() {

		this.mTaskStatus = false;
		this.blockTaskQueueWeakRef.get().remove(this);
		CurrentRunningTask.removeCurrentShowingTask();
		log.info("{}-{}", TAG, blockTaskQueueWeakRef.get().size());
	}

	/**
	 * 设置任务优先级实现
	 *
	 * @param mTaskPriority
	 * @return
	 */
	@Override
	public TaskInterface setPriority(TaskPriorityEnum mTaskPriority) {
		this.mTaskPriority = mTaskPriority;
		return this;
	}

	@Override
	public TaskInterface setTaskParamsJson(String taskParamsJson) {
		this.taskParamsJson = taskParamsJson;
		return this;
	}

	/**
	 * 设置任务执行时间
	 *
	 * @param duration
	 * @return
	 */
	public TaskInterface setDuration(int duration) {
		this.duration = duration;
		return this;
	}

	/**
	 * 获取任务优先级
	 *
	 * @return
	 */
	@Override
	public TaskPriorityEnum getPriority() {
		return mTaskPriority;
	}

	/**
	 * 获取任务执行时间
	 *
	 * @return
	 */
	@Override
	public int getDuration() {
		return duration;
	}

	/**
	 * 设置任务次序
	 *
	 * @param mSequence
	 */
	@Override
	public void setSequence(int mSequence) {
		this.mSequence = mSequence;
	}

	/**
	 * 获取任务次序
	 *
	 * @return
	 */
	@Override
	public int getSequence() {
		return mSequence;
	}

	// 获取任务状态
	@Override
	public boolean getStatus() {
		return mTaskStatus;
	}

	// 阻塞任务执行
	@Override
	public void blockTask() throws Exception {
		// 如果队列里面没数据,就会一直阻塞
		blockQueue.take();
	}

	// 解除阻塞
	@Override
	public void unLockBlock() {
		// 往里面随便添加一个数据,阻塞就会解除
		blockQueue.add(1);
	}

	/**
	 * 排队实现
	 * 优先级的标准如下:
	 * TaskPriority.LOW < TaskPriority.DEFAULT < TaskPriority.HIGH
	 * 当优先级相同 按照插入次序排队
	 */
	@Override
	public int compareTo(TaskInterface another) {
		final TaskPriorityEnum me = this.getPriority();
		final TaskPriorityEnum it = another.getPriority();
		return me == it ? this.getSequence()-another.getSequence() : it.ordinal()-me.ordinal();
	}

	// 输出一些信息
	@Override
	public String toString() {
		return "task name : " + getClass().getSimpleName() + " sequence : " + mSequence + " TaskPriority : " + mTaskPriority;
	}
}
