package com.qmth.distributed.print.business.bean.flow.link;

import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import io.swagger.annotations.ApiModelProperty;

import java.io.Serializable;
import java.util.Objects;

/**
 * @Description: 流程节点链表
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2022/1/26
 */
public class FlowTaskLink implements Serializable {

    @ApiModelProperty(name = "头节点")
    FlowTaskNode first;

    @ApiModelProperty(name = "尾节点")
    FlowTaskNode last;

    @ApiModelProperty(name = "长度")
    volatile int size;

    public FlowTaskLink() {
        this.size = 0;
    }

    public FlowTaskLink(FlowTaskNode first) {
        this.size = 1;
        this.first = first;
    }

    /**
     * 增加头节点
     *
     * @param first
     * @return
     */
    public boolean addFirst(FlowTaskNode first) {
        first.next = this.first;
        this.first.before = first;
        this.first = first;
        this.size++;
        return true;
    }

    /**
     * 增加尾节点
     *
     * @param last
     * @return
     */
    public boolean addLast(FlowTaskNode last) {
        this.last.next = last;
        last.before = this.last;
        this.last = last;
        this.size++;
        return true;
    }

    /**
     * 新增节点
     *
     * @param node
     * @return
     */
    public boolean add(FlowTaskNode node) {
        if (Objects.isNull(this.first)) {
            this.first = node;
        } else {
            FlowTaskNode flowTaskNode = this.first.next;
            if (Objects.isNull(flowTaskNode)) {
                this.first.next = node;
                node.before = this.first;
            } else {
                boolean next = true;
                while (next) {
                    if (Objects.nonNull(flowTaskNode.next)) {
                        flowTaskNode = flowTaskNode.next;
                    } else {
                        flowTaskNode.next = node;
                        node.before = flowTaskNode;
                        next = false;
                    }
                }
            }
            this.last = node;
        }
        this.size++;
        return true;
    }

    /**
     * 删除节点
     *
     * @param node
     * @return
     */
    public boolean remove(FlowTaskNode node) {
        if (this.size == 0) {
            throw ExceptionResultEnum.ERROR.exception("没有数据");
        } else if (this.first.getTask().getType() == node.getTask().getType() &&
                Objects.equals(this.first.getTask().getId(), node.getTask().getId())) {
            if (Objects.nonNull(this.first.next)) {
                this.first = this.first.next;
                this.first.before = null;
            } else {
                this.first = null;
            }
        } else if (this.last.getTask().getType() == node.getTask().getType() &&
                Objects.equals(this.last.getTask().getId(), node.getTask().getId())) {
            if (Objects.nonNull(this.last.before)) {
                this.last = this.last.before;
                this.last.next = null;
            }
        } else {
            FlowTaskNode flowTaskNode = this.first.next;
            boolean next = true;
            while (next) {
                if (flowTaskNode.getTask().getType() == node.getTask().getType() &&
                        Objects.equals(flowTaskNode.getTask().getId(), node.getTask().getId())) {
                    flowTaskNode.before.next = flowTaskNode.next;
                    flowTaskNode.next.before = flowTaskNode.before;
                    next = false;
                }
            }
        }
        this.size--;
        return true;
    }

    /**
     * 删除节点
     *
     * @param index
     * @return
     */
    public boolean remove(int index) {
        if (index < 0) {
            throw ExceptionResultEnum.ERROR.exception("index必须大于0");
        } else if (index >= this.size) {
            throw ExceptionResultEnum.ERROR.exception("index已超过链表最大值");
        } else if (index == 0) {
            if (Objects.nonNull(this.first.next)) {
                this.first = this.first.next;
                this.first.before = null;
            } else {
                this.first = null;
            }
        } else if (index == this.size - 1) {
            if (Objects.nonNull(this.last.before)) {
                this.last = this.last.before;
                this.last.next = null;
            }
        } else {
            FlowTaskNode flowTaskNode = this.first.next;
            for (int i = 1; i < this.size; i++) {
                if (i == index) {
                    flowTaskNode.before.next = flowTaskNode.next;
                    flowTaskNode.next.before = flowTaskNode.before;
                    break;
                }
                flowTaskNode = flowTaskNode.next;
            }
        }
        this.size--;
        return true;
    }

    /**
     * 根据下标新增节点
     *
     * @param index
     * @param node
     * @return
     */
    public boolean add(int index, FlowTaskNode node) {
        if (index < 0) {
            throw ExceptionResultEnum.ERROR.exception("index必须大于0");
        } else if (index > this.size) {
            throw ExceptionResultEnum.ERROR.exception("index已超过链表最大值");
        } else if (index == 0) {
            node.next = this.first;
            this.first.before = node;
            this.first = node;
        } else {
            if (this.size == index) {
                this.last.next = node;
                node.before = this.last;
                this.last = node;
            } else {
                FlowTaskNode flowTaskNode = first.next;
                for (int i = 1; i < this.size; i++) {
                    if (i == index) {
                        node.before = flowTaskNode.before;
                        node.next = flowTaskNode;
                        flowTaskNode.before.next = node;
                        flowTaskNode.before = node;
                        break;
                    }
                    flowTaskNode = flowTaskNode.next;
                }
            }
        }
        this.size++;
        return true;
    }

    /**
     * 是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        return this.size == 0;
    }

    /**
     * 根据下标获取
     *
     * @param index
     * @return
     */
    public FlowTaskNode get(int index) {
        FlowTaskNode flowTaskNode = null;
        if (index < 0) {
            throw ExceptionResultEnum.ERROR.exception("index必须大于0");
        } else if (index > this.size) {
            throw ExceptionResultEnum.ERROR.exception("index已超过链表最大值");
        } else if (index == 0) {
            flowTaskNode = this.first;
        } else if (index == this.size - 1) {
            flowTaskNode = this.last;
        } else {
            flowTaskNode = first.next;
            for (int i = 1; i < this.size; i++) {
                if (i == index) {
                    break;
                }
                flowTaskNode = flowTaskNode.next;
            }
        }
        return flowTaskNode;
    }

    /**
     * 大小
     *
     * @return
     */
    public int size() {
        return this.size <= 0 ? 0 : this.size;
    }

    public FlowTaskNode getFirst() {
        return first;
    }

    public void setFirst(FlowTaskNode first) {
        this.first = first;
    }

    public FlowTaskNode getLast() {
        return last;
    }

    public void setLast(FlowTaskNode last) {
        this.last = last;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }
}
