/**
 * Copyright (c) 2018, Intel Corporation
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Intel Corporation nor the names of its contributors
 *       may be used to endorse or promote products derived from this software
 *       without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.intel.stl.api.management.qosgroups;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import com.intel.stl.api.management.XMLConstants;
import com.intel.stl.api.management.virtualfabrics.Bandwidth;
import com.intel.stl.api.management.virtualfabrics.BaseSL;
import com.intel.stl.api.management.virtualfabrics.Enable;
import com.intel.stl.api.management.virtualfabrics.FlowControlDisable;
import com.intel.stl.api.management.virtualfabrics.HighPriority;
import com.intel.stl.api.management.virtualfabrics.HoqLife;
import com.intel.stl.api.management.virtualfabrics.PktLifeTimeMult;
import com.intel.stl.api.management.virtualfabrics.PreemptRank;
import com.intel.stl.api.management.virtualfabrics.RespSL;

@XmlRootElement(name = XMLConstants.QOSGROUP)
@XmlAccessorType(XmlAccessType.FIELD)
public class QOSGroup {

    @XmlElement(name = XMLConstants.NAME)
    private String name;

    @XmlElement(name = XMLConstants.ENABLE, type = Enable.class)
    private Enable enable;

    @XmlElement(name = XMLConstants.HIGH_PRIORITY, type = HighPriority.class)
    private HighPriority highPriority;

    @XmlElement(name = XMLConstants.BANDWIDTH, type = Bandwidth.class)
    private Bandwidth bandwidth;

    @XmlElement(name = XMLConstants.PKT_LT_MULT, type = PktLifeTimeMult.class)
    private PktLifeTimeMult pktLifeTimeMult;

    @XmlElement(name = XMLConstants.BASE_SL, type = BaseSL.class)
    private BaseSL baseSL;

    @XmlElement(name = XMLConstants.RESP_SL, type = RespSL.class)
    private RespSL respSL;

    @XmlElement(name = XMLConstants.FLOW_CONTR_DISABLE,
            type = FlowControlDisable.class)
    private FlowControlDisable flowControlDisable;

    @XmlElement(name = XMLConstants.PREEMPT_RANK, type = PreemptRank.class)
    private PreemptRank preemptRank;

    @XmlElement(name = XMLConstants.HOQ_LIFE, type = HoqLife.class)
    private HoqLife hoqLife;

    @XmlElement(name = XMLConstants.MULTICAST_SL, type = MulticastSL.class)
    private MulticastSL multicaseSL;

    /**
     * Description:
     *
     * @param name
     */
    public QOSGroup(String name) {
        super();
        this.name = name;
        enable = new Enable(false);
    }

    public QOSGroup() {
        this(null);

    }

    /**
     * @return the enable
     */
    public Enable getEnable() {
        return enable;
    }

    /**
     * @param enable
     *            the enable to set
     */
    public void setEnable(Enable enable) {
        this.enable = enable;
    }

    /**
     * @return the bandwidth
     */
    public Bandwidth getBandwidth() {
        return bandwidth;
    }

    /**
     * @param bandwidth
     *            the bandwidth to set
     */
    public void setBandwidth(Bandwidth bandwidth) {
        this.bandwidth = bandwidth;
    }

    /**
     * @return the pktLifeTimeMult
     */
    public PktLifeTimeMult getPktLifeTimeMult() {
        return pktLifeTimeMult;
    }

    /**
     * @param pktLifeTimeMult
     *            the pktLifeTimeMult to set
     */
    public void setPktLifeTimeMult(PktLifeTimeMult pktLifeTimeMult) {
        this.pktLifeTimeMult = pktLifeTimeMult;
    }

    /**
     * @return the baseSL
     */
    public BaseSL getBaseSL() {
        return baseSL;
    }

    /**
     * @param baseSL
     *            the baseSL to set
     */
    public void setBaseSL(BaseSL baseSL) {
        this.baseSL = baseSL;
    }

    /**
     * @return the respSL
     */
    public RespSL getRespSL() {
        return respSL;
    }

    /**
     * @param respSL the respSL to set
     */
    public void setRespSL(RespSL respSL) {
        this.respSL = respSL;
    }

    /**
     * @return the flowControlDisable
     */
    public FlowControlDisable getFlowControlDisable() {
        return flowControlDisable;
    }

    /**
     * @param flowControlDisable
     *            the flowControlDisable to set
     */
    public void setFlowControlDisable(FlowControlDisable flowControlDisable) {
        this.flowControlDisable = flowControlDisable;
    }

    /**
     * @return the preemptRank
     */
    public PreemptRank getPreemptRank() {
        return preemptRank;
    }

    /**
     * @param preemptRank
     *            the preemptRank to set
     */
    public void setPreemptRank(PreemptRank preemptRank) {
        this.preemptRank = preemptRank;
    }

    /**
     * @return the hoqLife
     */
    public HoqLife getHoqLife() {
        return hoqLife;
    }

    /**
     * @param hoqLife
     *            the hoqLife to set
     */
    public void setHoqLife(HoqLife hoqLife) {
        this.hoqLife = hoqLife;
    }

    /**
     * @return the multicaseSL
     */
    public MulticastSL getMulticaseSL() {
        return multicaseSL;
    }

    /**
     * @param multicaseSL
     *            the multicaseSL to set
     */
    public void setMulticaseSL(MulticastSL multicaseSL) {
        this.multicaseSL = multicaseSL;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the highPriority
     */
    public HighPriority getHighPriority() {
        return highPriority;
    }

    /**
     * @param highPriority
     *            the highPriority to set
     */
    public void setHighPriority(HighPriority highPriority) {
        this.highPriority = highPriority;
    }

    public void clear() {
        highPriority = null;
        bandwidth = null;
        pktLifeTimeMult = null;
        baseSL = null;
        respSL = null;
        flowControlDisable = null;
        preemptRank = null;
        hoqLife = null;
        multicaseSL = null;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((bandwidth == null) ? 0 : bandwidth.hashCode());
        result = prime * result + ((baseSL == null) ? 0 : baseSL.hashCode());
        result = prime * result + ((respSL == null) ? 0 : respSL.hashCode());
        result = prime * result + ((enable == null) ? 0 : enable.hashCode());
        result = prime * result + ((flowControlDisable == null) ? 0
                : flowControlDisable.hashCode());
        result = prime * result
                + ((highPriority == null) ? 0 : highPriority.hashCode());
        result = prime * result + ((hoqLife == null) ? 0 : hoqLife.hashCode());
        result = prime * result
                + ((multicaseSL == null) ? 0 : multicaseSL.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result
                + ((pktLifeTimeMult == null) ? 0 : pktLifeTimeMult.hashCode());
        result = prime * result
                + ((preemptRank == null) ? 0 : preemptRank.hashCode());
        return result;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        QOSGroup other = (QOSGroup) obj;
        if (bandwidth == null) {
            if (other.bandwidth != null) {
                return false;
            }
        } else if (!bandwidth.equals(other.bandwidth)) {
            return false;
        }
        if (baseSL == null) {
            if (other.baseSL != null) {
                return false;
            }
        } else if (!baseSL.equals(other.baseSL)) {
            return false;
        }
        if (respSL == null) {
            if (other.respSL != null) {
                return false;
            }
        } else if (!respSL.equals(other.respSL)) {
            return false;
        }
        if (enable == null) {
            if (other.enable != null) {
                return false;
            }
        } else if (!enable.equals(other.enable)) {
            return false;
        }
        if (flowControlDisable == null) {
            if (other.flowControlDisable != null) {
                return false;
            }
        } else if (!flowControlDisable.equals(other.flowControlDisable)) {
            return false;
        }
        if (highPriority == null) {
            if (other.highPriority != null) {
                return false;
            }
        } else if (!highPriority.equals(other.highPriority)) {
            return false;
        }
        if (hoqLife == null) {
            if (other.hoqLife != null) {
                return false;
            }
        } else if (!hoqLife.equals(other.hoqLife)) {
            return false;
        }
        if (multicaseSL == null) {
            if (other.multicaseSL != null) {
                return false;
            }
        } else if (!multicaseSL.equals(other.multicaseSL)) {
            return false;
        }
        if (name == null) {
            if (other.name != null) {
                return false;
            }
        } else if (!name.equals(other.name)) {
            return false;
        }
        if (pktLifeTimeMult == null) {
            if (other.pktLifeTimeMult != null) {
                return false;
            }
        } else if (!pktLifeTimeMult.equals(other.pktLifeTimeMult)) {
            return false;
        }
        if (preemptRank == null) {
            if (other.preemptRank != null) {
                return false;
            }
        } else if (!preemptRank.equals(other.preemptRank)) {
            return false;
        }
        return true;
    }

    public QOSGroup copy() {
        QOSGroup qosGroup = new QOSGroup(name);
        qosGroup.enable = enable.copy();
        if (highPriority != null) {
            qosGroup.highPriority = highPriority.copy();
        }
        if (bandwidth != null) {
            qosGroup.bandwidth = bandwidth.copy();
        }
        if (pktLifeTimeMult != null) {
            qosGroup.pktLifeTimeMult = pktLifeTimeMult.copy();
        }
        if (baseSL != null) {
            qosGroup.baseSL = baseSL.copy();
        }
        if (respSL != null) {
            qosGroup.respSL = respSL.copy();
        }
        if (flowControlDisable != null) {
            qosGroup.flowControlDisable = flowControlDisable.copy();
        }
        if (preemptRank != null) {
            qosGroup.preemptRank = preemptRank.copy();
        }
        if (hoqLife != null) {
            qosGroup.hoqLife = hoqLife.copy();
        }
        if (multicaseSL != null) {
            qosGroup.multicaseSL = multicaseSL.copy();
        }
        return qosGroup;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "QOSGroup [name=" + name + ", enable=" + enable
                + ", highPriority=" + highPriority + ", bandwidth=" + bandwidth
                + ", pktLifeTimeMult=" + pktLifeTimeMult + ", baseSL=" + baseSL
                + ", respSL=" + respSL + ", flowControlDisable="
                + flowControlDisable + ", preemptRank=" + preemptRank
                + ", hoqLife=" + hoqLife + ", multicaseSL=" + multicaseSL
                + "]";
    }

}
