/*
 * Copyright 2017-2023 Open Networking Foundation (ONF) and the ONF Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.opencord.sadis;

import com.fasterxml.jackson.annotation.JsonProperty;
import org.onlab.packet.VlanId;

import java.util.Objects;

/**
 * Represents a unit of information about a service.
 */
public final class UniTagInformation {

    @JsonProperty(value = "uniTagMatch")
    private VlanId uniTagMatch = VlanId.vlanId(VlanId.NO_VID);

    @JsonProperty(value = "ponCTag")
    private VlanId ponCTag;

    @JsonProperty(value = "ponSTag")
    private VlanId ponSTag;

    @JsonProperty(value = "usPonCTagPriority")
    private int usPonCTagPriority = -1;

    @JsonProperty(value = "usPonSTagPriority")
    private int usPonSTagPriority = -1;

    @JsonProperty(value = "dsPonCTagPriority")
    private int dsPonCTagPriority = -1;

    @JsonProperty(value = "dsPonSTagPriority")
    private int dsPonSTagPriority = -1;

    @JsonProperty(value = "technologyProfileId")
    private int technologyProfileId = -1;

    @JsonProperty(value = "upstreamBandwidthProfile")
    private String upstreamBandwidthProfile;

    @JsonProperty(value = "downstreamBandwidthProfile")
    private String downstreamBandwidthProfile;

    @JsonProperty(value = "upstreamOltBandwidthProfile")
    private String upstreamOltBandwidthProfile;

    @JsonProperty(value = "downstreamOltBandwidthProfile")
    private String downstreamOltBandwidthProfile;

    @JsonProperty(value = "serviceName")
    private String serviceName;

    @JsonProperty(value = "enableMacLearning")
    private boolean enableMacLearning = false;

    @JsonProperty(value = "configuredMacAddress")
    private String configuredMacAddress;

    @JsonProperty(value = "isDhcpRequired")
    private boolean isDhcpRequired;

    @JsonProperty(value = "isIgmpRequired")
    private boolean isIgmpRequired;

    @JsonProperty(value = "isPppoeRequired")
    private boolean isPppoeRequired;

    public UniTagInformation() {

    }
    //CHECKSTYLE:OFF
    private UniTagInformation(final VlanId uniTagMatch, final VlanId ponCTag, final VlanId ponSTag,
                              final int usPonCTagPriority, final int usPonSTagPriority,
                              final int dsPonCTagPriority, final int dsPonSTagPriority,
                              final int technologyProfileId,
                              final String upstreamBandwidthProfile,
                              final String downstreamBandwidthProfile,
                              final String upstreamOltBandwidthProfile,
                              final String downstreamOltBandwidthProfile,
                              final String serviceName, final boolean enableMacLearning,
                              final String configuredMacAddress, final boolean isDhcpRequired,
                              final boolean isIgmpRequired, final boolean isPppoeRequired) {
        this.uniTagMatch = uniTagMatch;
        this.ponCTag = ponCTag;
        this.ponSTag = ponSTag;
        this.usPonCTagPriority = usPonCTagPriority;
        this.usPonSTagPriority = usPonSTagPriority;
        this.dsPonCTagPriority = dsPonCTagPriority;
        this.dsPonSTagPriority = dsPonSTagPriority;
        this.technologyProfileId = technologyProfileId;
        this.upstreamBandwidthProfile = upstreamBandwidthProfile;
        this.downstreamBandwidthProfile = downstreamBandwidthProfile;
        this.upstreamOltBandwidthProfile = upstreamOltBandwidthProfile;
        this.downstreamOltBandwidthProfile = downstreamOltBandwidthProfile;
        this.serviceName = serviceName;
        this.enableMacLearning = enableMacLearning;
        this.configuredMacAddress = configuredMacAddress;
        this.isDhcpRequired = isDhcpRequired;
        this.isIgmpRequired = isIgmpRequired;
        this.isPppoeRequired = isPppoeRequired;
    }
    //CHECKSTYLE:ON

    public final VlanId getUniTagMatch() {
        return uniTagMatch;
    }

    public final VlanId getPonCTag() {
        return ponCTag;
    }

    public final VlanId getPonSTag() {
        return ponSTag;
    }

    public final int getUsPonCTagPriority() {
        return usPonCTagPriority;
    }

    public final int getUsPonSTagPriority() {
        return usPonSTagPriority;
    }

    public final int getDsPonCTagPriority() {
        return dsPonCTagPriority;
    }

    public final int getDsPonSTagPriority() {
        return dsPonSTagPriority;
    }

    public final int getTechnologyProfileId() {
        return technologyProfileId;
    }

    public final String getUpstreamBandwidthProfile() {
        return upstreamBandwidthProfile;
    }

    public final String getDownstreamBandwidthProfile() {
        return downstreamBandwidthProfile;
    }

    public final String getUpstreamOltBandwidthProfile() {
        return upstreamOltBandwidthProfile;
    }

    public final String getDownstreamOltBandwidthProfile() {
        return downstreamOltBandwidthProfile;
    }

    public final String getServiceName() {
        return serviceName;
    }

    public final boolean getEnableMacLearning() {
        return enableMacLearning;
    }

    public final String getConfiguredMacAddress() {
        return configuredMacAddress;
    }

    public final boolean getIsDhcpRequired() {
        return isDhcpRequired;
    }

    public final boolean getIsIgmpRequired() {
        return isIgmpRequired;
    }

    public final boolean getIsPppoeRequired() {
        return isPppoeRequired;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        UniTagInformation that = (UniTagInformation) o;

        if (!Objects.equals(uniTagMatch, that.uniTagMatch)) {
            return false;
        }
        if (technologyProfileId != that.technologyProfileId) {
            return false;
        }
        if (!Objects.equals(ponCTag, that.ponCTag)) {
            return false;
        }
        if (!Objects.equals(ponSTag, that.ponSTag)) {
            return false;
        }
        if (usPonCTagPriority != that.usPonCTagPriority) {
            return false;
        }
        if (usPonSTagPriority != that.usPonSTagPriority) {
            return false;
        }
        if (dsPonCTagPriority != that.dsPonCTagPriority) {
            return false;
        }
        if (dsPonSTagPriority != that.dsPonSTagPriority) {
            return false;
        }
        if (enableMacLearning != that.enableMacLearning) {
            return false;
        }
        if (!Objects.equals(configuredMacAddress, that.configuredMacAddress)) {
            return false;
        }
        if (isDhcpRequired != that.isDhcpRequired) {
            return false;
        }
        if (isIgmpRequired != that.isIgmpRequired) {
            return false;
        }
        if (isPppoeRequired != that.isPppoeRequired) {
            return false;
        }
        if (upstreamBandwidthProfile != null ? !upstreamBandwidthProfile.equals(that.upstreamBandwidthProfile) :
                that.upstreamBandwidthProfile != null) {
            return false;
        }
        if (downstreamBandwidthProfile != null ? !downstreamBandwidthProfile.equals(that.downstreamBandwidthProfile) :
                that.downstreamBandwidthProfile != null) {
            return false;
        }
        if (upstreamOltBandwidthProfile != null ?
                !upstreamOltBandwidthProfile.equals(that.upstreamOltBandwidthProfile) :
                that.upstreamOltBandwidthProfile != null) {
            return false;
        }
        if (downstreamOltBandwidthProfile != null ?
                !downstreamOltBandwidthProfile.equals(that.downstreamOltBandwidthProfile) :
                that.downstreamOltBandwidthProfile != null) {
            return false;
        }
        return serviceName != null ? serviceName.equals(that.serviceName) : that.serviceName == null;
    }

    @Override
    public int hashCode() {
        int result = uniTagMatch != null ? uniTagMatch.hashCode() : 0;
        result = 31 * result + (ponCTag != null ? ponCTag.hashCode() : 0);
        result = 31 * result + (ponSTag != null ? ponSTag.hashCode() : 0);
        result = 31 * result + usPonCTagPriority;
        result = 31 * result + usPonSTagPriority;
        result = 31 * result + dsPonCTagPriority;
        result = 31 * result + dsPonSTagPriority;
        result = 31 * result + technologyProfileId;
        result = 31 * result + (upstreamBandwidthProfile != null ? upstreamBandwidthProfile.hashCode() : 0);
        result = 31 * result + (downstreamBandwidthProfile != null ? downstreamBandwidthProfile.hashCode() : 0);
        result = 31 * result + (upstreamOltBandwidthProfile != null ? upstreamOltBandwidthProfile.hashCode() : 0);
        result = 31 * result + (downstreamOltBandwidthProfile != null ? downstreamOltBandwidthProfile.hashCode() : 0);
        result = 31 * result + (serviceName != null ? serviceName.hashCode() : 0);
        result = 31 * result + (enableMacLearning ? 1 : 0);
        result = 31 * result + (configuredMacAddress != null ? configuredMacAddress.hashCode() : 0);
        result = 31 * result + (isDhcpRequired ? 1 : 0);
        result = 31 * result + (isIgmpRequired ? 1 : 0);
        result = 31 * result + (isPppoeRequired ? 1 : 0);
        return result;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("UniTagInformation{");
        sb.append("uniTagMatch=").append(uniTagMatch);
        sb.append(", ponCTag=").append(ponCTag);
        sb.append(", ponSTag=").append(ponSTag);
        sb.append(", usPonCTagPriority=").append(usPonCTagPriority);
        sb.append(", usPonSTagPriority=").append(usPonSTagPriority);
        sb.append(", dsPonCTagPriority=").append(dsPonCTagPriority);
        sb.append(", dsPonSTagPriority=").append(dsPonSTagPriority);
        sb.append(", technologyProfileId=").append(technologyProfileId);
        sb.append(", enableMacLearning=").append(enableMacLearning);
        sb.append(", upstreamBandwidthProfile='").append(upstreamBandwidthProfile).append('\'');
        sb.append(", downstreamBandwidthProfile='").append(downstreamBandwidthProfile).append('\'');
        sb.append(", upstreamOltBandwidthProfile='").append(upstreamOltBandwidthProfile).append('\'');
        sb.append(", downstreamOltBandwidthProfile='").append(downstreamOltBandwidthProfile).append('\'');
        sb.append(", serviceName='").append(serviceName).append('\'');
        sb.append(", configuredMacAddress='").append(configuredMacAddress).append('\'');
        sb.append(", isDhcpRequired=").append(isDhcpRequired);
        sb.append(", isIgmpRequired=").append(isIgmpRequired);
        sb.append(", isPppoeRequired=").append(isPppoeRequired);
        sb.append('}');
        return sb.toString();
    }

    public static final class Builder {

        private VlanId uniTagMatch;
        private VlanId ponCTag;
        private VlanId ponSTag;
        private int usPonCTagPriority = -1;
        private int usPonSTagPriority = -1;
        private int dsPonCTagPriority = -1;
        private int dsPonSTagPriority = -1;
        private int technologyProfileId;
        private String upstreamBandwidthProfile;
        private String downstreamBandwidthProfile;
        private String upstreamOltBandwidthProfile;
        private String downstreamOltBandwidthProfile;
        private String serviceName;
        private boolean enableMacLearning;
        private String configuredMacAddress;
        private boolean isDhcpRequired;
        private boolean isIgmpRequired;
        private boolean isPppoeRequired;

        public final Builder setUniTagMatch(final VlanId uniTagMatch) {
            this.uniTagMatch = uniTagMatch;
            return this;
        }

        public final Builder setPonCTag(final VlanId ponCTag) {
            this.ponCTag = ponCTag;
            return this;
        }

        public final Builder setPonSTag(final VlanId ponSTag) {
            this.ponSTag = ponSTag;
            return this;
        }

        public final Builder setUsPonCTagPriority(final int usPonCTagPriority) {
            this.usPonCTagPriority = usPonCTagPriority;
            return this;
        }

        public final Builder setUsPonSTagPriority(final int usPonSTagPriority) {
            this.usPonSTagPriority = usPonSTagPriority;
            return this;
        }

        public final Builder setDsPonCTagPriority(final int dsPonCTagPriority) {
            this.dsPonCTagPriority = dsPonCTagPriority;
            return this;
        }

        public final Builder setDsPonSTagPriority(final int dsPonSTagPriority) {
            this.dsPonSTagPriority = dsPonSTagPriority;
            return this;
        }

        public final Builder setTechnologyProfileId(final int technologyProfileId) {
            this.technologyProfileId = technologyProfileId;
            return this;
        }

        public final Builder setUpstreamBandwidthProfile(final String upstreamBandwidthProfile) {
            this.upstreamBandwidthProfile = upstreamBandwidthProfile;
            return this;
        }

        public final Builder setDownstreamBandwidthProfile(final String downstreamBandwidthProfile) {
            this.downstreamBandwidthProfile = downstreamBandwidthProfile;
            return this;
        }

        public final Builder setUpstreamOltBandwidthProfile(final String upstreamOltBandwidthProfile) {
            this.upstreamOltBandwidthProfile = upstreamOltBandwidthProfile;
            return this;
        }

        public final Builder setDownstreamOltBandwidthProfile(final String downstreamOltBandwidthProfile) {
            this.downstreamOltBandwidthProfile = downstreamOltBandwidthProfile;
            return this;
        }

        public final Builder setServiceName(final String serviceName) {
            this.serviceName = serviceName;
            return this;
        }

        public final Builder setEnableMacLearning(final boolean enableMacLearning) {
            this.enableMacLearning = enableMacLearning;
            return this;
        }

        public final Builder setConfiguredMacAddress(final String configuredMacAddress) {
            this.configuredMacAddress = configuredMacAddress;
            return this;
        }

        public final Builder setIsDhcpRequired(final boolean isDhcpRequired) {
            this.isDhcpRequired = isDhcpRequired;
            return this;
        }

        public final Builder setIsIgmpRequired(final boolean isIgmpRequired) {
            this.isIgmpRequired = isIgmpRequired;
            return this;
        }

        public final Builder setIsPppoeRequired(final boolean isPppoeRequired) {
            this.isPppoeRequired = isPppoeRequired;
            return this;
        }

        public final UniTagInformation build() {
            return new UniTagInformation(this.uniTagMatch, this.ponCTag,
                    this.ponSTag, this.usPonCTagPriority, this.usPonSTagPriority,
                    this.dsPonCTagPriority, this.dsPonSTagPriority, this.technologyProfileId,
                    this.upstreamBandwidthProfile, this.downstreamBandwidthProfile,
                    this.upstreamOltBandwidthProfile, this.downstreamOltBandwidthProfile,
                    this.serviceName, this.enableMacLearning, this.configuredMacAddress,
                    this.isDhcpRequired, this.isIgmpRequired, this.isPppoeRequired);
        }
    }
}
