/*
 * Copyright 2018-present Open Networking Foundation
 *
 * 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.onosproject.openstacktelemetry.impl;

import com.google.common.base.MoreObjects;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.TpPort;
import org.onosproject.openstacktelemetry.api.StatsFlowRule;

import java.util.Objects;

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

public final class DefaultStatsFlowRule implements StatsFlowRule {
    private final IpPrefix srcIpPrefix;
    private final IpPrefix dstIpPrefix;
    private final byte     ipProtocol;
    private final TpPort   srcTpPort;
    private final TpPort   dstTpPort;

    private static final String NOT_NULL_MSG = "Element % cannot be null";

    protected DefaultStatsFlowRule(IpPrefix srcIpPrefix,
                                   IpPrefix dstIpPrefix,
                                   byte ipProtoco,
                                   TpPort srcTpPort,
                                   TpPort dstTpPort) {
        this.srcIpPrefix = srcIpPrefix;
        this.dstIpPrefix = dstIpPrefix;
        this.ipProtocol  = ipProtoco;
        this.srcTpPort   = srcTpPort;
        this.dstTpPort   = dstTpPort;
    }

    @Override
    public IpPrefix srcIpPrefix() {
        return srcIpPrefix;
    }

    @Override
    public IpPrefix dstIpPrefix() {
        return dstIpPrefix;
    }

    @Override
    public byte ipProtocol() {
        return ipProtocol;
    }

    @Override
    public TpPort srcTpPort() {
        return srcTpPort;
    }

    @Override
    public TpPort dstTpPort() {
        return dstTpPort;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("srcIpPrefix", srcIpPrefix)
                .add("dstIpPrefix", dstIpPrefix)
                .add("ipProtocol", ipProtocol)
                .add("srcTpPort", srcTpPort)
                .add("dstTpPort", dstTpPort)
                .toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj instanceof DefaultStatsFlowRule) {
            final DefaultStatsFlowRule other = (DefaultStatsFlowRule) obj;
            return Objects.equals(this.srcIpPrefix, other.srcIpPrefix) &&
                    Objects.equals(this.dstIpPrefix, other.dstIpPrefix) &&
                    Objects.equals(this.srcTpPort, other.srcTpPort) &&
                    Objects.equals(this.dstTpPort, other.dstTpPort) &&
                    Objects.equals(this.ipProtocol, other.ipProtocol);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(srcIpPrefix, dstIpPrefix, srcTpPort, dstTpPort, ipProtocol);
    }

    /**
     * Obtains a default stats flow rule builder object.
     *
     * @return flow rule builder object
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Obtains the builder object existing flow rule.
     *
     * @param flowRule flow rule
     * @return builder object
     */
    public static Builder from(StatsFlowRule flowRule) {
        return new Builder()
                .srcIpPrefix(flowRule.srcIpPrefix())
                .dstIpPrefix(flowRule.dstIpPrefix())
                .ipProtocol(flowRule.ipProtocol())
                .srcTpPort(flowRule.srcTpPort())
                .dstTpPort(flowRule.dstTpPort());
    }

    /**
     * A builder class for openstack flow rule.
     */
    public static final class Builder implements StatsFlowRule.Builder {
        private IpPrefix srcIpPrefix;
        private IpPrefix dstIpPrefix;
        private byte     ipProtocol;
        private TpPort   srcTpPort;
        private TpPort   dstTpPort;

        // private constructor not intended to use from external
        private Builder() {
        }

        @Override
        public DefaultStatsFlowRule build() {
            checkArgument(srcIpPrefix != null, NOT_NULL_MSG, "Source IP Prefix");
            checkArgument(dstIpPrefix != null, NOT_NULL_MSG, "Destination IP Prefix");

            return new DefaultStatsFlowRule(srcIpPrefix,
                                                dstIpPrefix,
                                                ipProtocol,
                                                srcTpPort,
                                                dstTpPort);
        }

        @Override
        public Builder srcIpPrefix(IpPrefix srcIpPrefix) {
            this.srcIpPrefix = srcIpPrefix;
            return this;
        }

        @Override
        public Builder dstIpPrefix(IpPrefix dstIpPrefix) {
            this.dstIpPrefix = dstIpPrefix;
            return this;
        }

        @Override
        public Builder ipProtocol(byte ipProtocol) {
            this.ipProtocol = ipProtocol;
            return this;
        }

        @Override
        public Builder srcTpPort(TpPort srcTpPort) {
            this.srcTpPort = srcTpPort;
            return this;
        }

        @Override
        public Builder dstTpPort(TpPort dstTpPort) {
            this.dstTpPort = dstTpPort;
            return this;
        }
    }
}
