package org.onosproject.incubator.net.resource.label;

import static com.google.common.base.Preconditions.checkArgument;

import java.util.Collections;
import java.util.Objects;
import java.util.Set;

import org.onosproject.net.DeviceId;

import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;

/**
 * Abstraction of the capacity of device label resource or global label
 * resource. it's contiguous range of label resource.when a application apply
 * some labels of some device,first catch from Set that store
 * available labels,if the size of the Set less than the apply number,then get
 * labels by calculating with three attributes, beginLabel,endLabel and
 * currentUsedMaxLabelId
 */
public class LabelResourcePool {

    private final DeviceId deviceId;
    private final LabelResourceId beginLabel;
    private final LabelResourceId endLabel;
    private final long totalNum; // capacity of label resource pool
    private final long usedNum; // have used label number
    private final LabelResourceId currentUsedMaxLabelId; // the maximal label
                                                        // number id
    private ImmutableSet<LabelResource> releaseLabelId; // Set of released label

    /**
     * Creates a pool by device id,begin label id,end label id.
     *
     * @param deviceId device identifier
     * @param beginLabel represents for the first label id in the range of label
     *            resource pool
     * @param endLabel represents for the last label id in the range of label
     *            resource pool
     */
    public LabelResourcePool(String deviceId, long beginLabel, long endLabel) {
        this(deviceId, beginLabel, endLabel, endLabel - beginLabel + 1, 0L,
             beginLabel, ImmutableSet.copyOf(Collections.emptySet()));
    }

    /**
     * Creates a pool by device id,begin label id,end label id.
     * used to update a pool in the store.
     * @param deviceId device identifier
     * @param beginLabel represents for the first label id in the range of label
     *            resource pool
     * @param endLabel represents for the last label id in the range of label
     *            resource pool
     * @param totalNum capacity of label resource pool
     * @param usedNum have used label number
     * @param currentUsedMaxLabelId the maximal label number id
     * @param releaseLabelId Set of released label
     */
    public LabelResourcePool(String deviceId, long beginLabel, long endLabel,
                             long totalNum, long usedNum,
                             long currentUsedMaxLabelId,
                             ImmutableSet<LabelResource> releaseLabelId) {
        checkArgument(endLabel >= beginLabel,
                      "endLabel %s must be greater than or equal to beginLabel %s",
                      endLabel, beginLabel);
        this.deviceId = DeviceId.deviceId(deviceId);
        this.beginLabel = LabelResourceId.labelResourceId(beginLabel);
        this.endLabel = LabelResourceId.labelResourceId(endLabel);
        this.totalNum = totalNum;
        this.usedNum = usedNum;
        this.currentUsedMaxLabelId = LabelResourceId
                .labelResourceId(currentUsedMaxLabelId);
        this.releaseLabelId = releaseLabelId;
    }

    /**
     * Returns a device id.
     *
     * @return DeviceId
     */
    public DeviceId deviceId() {
        return deviceId;
    }

    /**
     * Returns a begin Label id.
     *
     * @return begin Label id
     */
    public LabelResourceId beginLabel() {
        return beginLabel;
    }

    /**
     * Returns a end Label id.
     *
     * @return end Label id
     */
    public LabelResourceId endLabel() {
        return endLabel;
    }

    /**
     * Returns a begin Label id.
     *
     * @return current Used Maximal Label Id
     */
    public LabelResourceId currentUsedMaxLabelId() {
        return currentUsedMaxLabelId;
    }

    /**
     * Returns total number.
     *
     * @return the total label number
     */
    public long totalNum() {
        return totalNum;
    }

    /**
     * Returns used number.
     *
     * @return the used label number
     */
    public long usedNum() {
        return usedNum;
    }

    /**
     * Returns the Set of released label before.
     *
     * @return the Set of LabelResource
     */
    public Set<LabelResource> releaseLabelId() {
        return releaseLabelId;
    }

    @Override
    public int hashCode() {
        return Objects.hash(this.deviceId, this.beginLabel, this.endLabel,
                            this.totalNum, this.usedNum,
                            this.currentUsedMaxLabelId, this.releaseLabelId);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof LabelResourcePool) {
            LabelResourcePool that = (LabelResourcePool) obj;
            return Objects.equals(this.deviceId, that.deviceId)
                    && Objects.equals(this.beginLabel, that.beginLabel)
                    && Objects.equals(this.endLabel, that.endLabel)
                    && Objects.equals(this.totalNum, that.totalNum)
                    && Objects.equals(this.usedNum, that.usedNum)
                    && Objects.equals(this.currentUsedMaxLabelId,
                                      that.currentUsedMaxLabelId)
                    && Objects.equals(this.releaseLabelId, that.releaseLabelId);
        }
        return false;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return MoreObjects.toStringHelper(this).add("deviceId", this.deviceId)
                .add("beginLabel", this.beginLabel)
                .add("endLabel", this.endLabel).add("totalNum", this.totalNum)
                .add("usedNum", this.usedNum)
                .add("currentUsedMaxLabelId", this.currentUsedMaxLabelId)
                .add("releaseLabelId", this.releaseLabelId).toString();
    }
}
