/*
 * 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 org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.openstacktelemetry.api.FlowInfo;
import org.onosproject.openstacktelemetry.api.StatsInfo;

import java.util.Objects;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Implementation class of FlowInfo.
 */
public final class DefaultFlowInfo implements FlowInfo {
    private static final String INGRESS_STATS = "Ingress Port :";
    private static final String EGRESS_STATS = "Egress Port :";

    private final byte flowType;
    private final DeviceId deviceId;
    private final int inputInterfaceId;
    private final int outputInterfaceId;
    private final VlanId vlanId;
    private final short vxlanId;
    private final IpPrefix srcIp;
    private final IpPrefix dstIp;
    private final TpPort srcPort;
    private final TpPort dstPort;
    private final byte protocol;
    private final MacAddress srcMac;
    private final MacAddress dstMac;
    private final StatsInfo statsInfo;

    private DefaultFlowInfo(byte flowType, DeviceId deviceId,
                            int inputInterfaceId, int outputInterfaceId,
                            VlanId vlanId, short vxlanId, IpPrefix srcIp,
                            IpPrefix dstIp, TpPort srcPort, TpPort dstPort,
                            byte protocol, MacAddress srcMac, MacAddress dstMac,
                            StatsInfo statsInfo) {
        this.flowType = flowType;
        this.deviceId = deviceId;
        this.inputInterfaceId = inputInterfaceId;
        this.outputInterfaceId = outputInterfaceId;
        this.vlanId = vlanId;
        this.vxlanId = vxlanId;
        this.srcIp = srcIp;
        this.dstIp = dstIp;
        this.srcPort = srcPort;
        this.dstPort = dstPort;
        this.protocol = protocol;
        this.srcMac = srcMac;
        this.dstMac = dstMac;
        this.statsInfo = statsInfo;
    }

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

    @Override
    public DeviceId deviceId() {
        return deviceId;
    }

    @Override
    public int inputInterfaceId() {
        return inputInterfaceId;
    }

    @Override
    public int outputInterfaceId() {
        return outputInterfaceId;
    }

    @Override
    public VlanId vlanId() {
        return vlanId;
    }

    @Override
    public short vxlanId() {
        return vxlanId;
    }

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

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

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

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

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

    @Override
    public MacAddress srcMac() {
        return srcMac;
    }

    @Override
    public MacAddress dstMac() {
        return dstMac;
    }

    @Override
    public StatsInfo statsInfo() {
        return statsInfo;
    }

    @Override
    public boolean roughEquals(FlowInfo flowInfo) {
        final DefaultFlowInfo other = (DefaultFlowInfo) flowInfo;
        return Objects.equals(this.deviceId, other.deviceId) &&
                Objects.equals(this.srcIp, other.srcIp) &&
                Objects.equals(this.dstIp, other.dstIp) &&
                Objects.equals(this.srcPort, other.srcPort) &&
                Objects.equals(this.dstPort, other.dstPort) &&
                Objects.equals(this.protocol, other.protocol);
    }

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

        if (obj instanceof DefaultFlowInfo) {
            final DefaultFlowInfo other = (DefaultFlowInfo) obj;
            return Objects.equals(this.flowType, other.flowType) &&
                    Objects.equals(this.deviceId, other.deviceId) &&
                    Objects.equals(this.inputInterfaceId, other.inputInterfaceId) &&
                    Objects.equals(this.outputInterfaceId, other.outputInterfaceId) &&
                    Objects.equals(this.vlanId, other.vlanId) &&
                    Objects.equals(this.vxlanId, other.vxlanId) &&
                    Objects.equals(this.srcIp, other.srcIp) &&
                    Objects.equals(this.dstIp, other.dstIp) &&
                    Objects.equals(this.srcPort, other.srcPort) &&
                    Objects.equals(this.dstPort, other.dstPort) &&
                    Objects.equals(this.protocol, other.protocol) &&
                    Objects.equals(this.srcMac, other.srcMac) &&
                    Objects.equals(this.dstMac, other.dstMac) &&
                    Objects.equals(this.statsInfo, other.statsInfo);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(flowType, deviceId, inputInterfaceId,
                outputInterfaceId, vlanId, vxlanId, srcIp, dstIp, srcPort, dstPort,
                protocol, srcMac, dstMac, statsInfo);
    }

    @Override
    public String uniqueFlowInfoKey() {
        if (srcIp.address().isZero() || dstIp.address().isZero()) {
            if (!srcIp.address().isZero()) {
                return INGRESS_STATS + srcIp.toString();
            }
            if (!dstIp.address().isZero()) {
                return EGRESS_STATS + dstIp.toString();
            }
        }
        return srcIp.toString() + ":" +
                ((srcPort == null) ? "any" : srcPort.toString()) +
                " -> " +
                dstIp.toString() + ":" +
                ((dstPort == null) ? "any" : dstPort.toString());
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("flowType", flowType)
                .add("deviceId", deviceId)
                .add("inputInterfaceId", inputInterfaceId)
                .add("outputInterfaceId", outputInterfaceId)
                .add("vlanId", vlanId)
                .add("vxlanId", vxlanId)
                .add("srcIp", srcIp)
                .add("dstIp", dstIp)
                .add("srcPort", srcPort)
                .add("dstPort", dstPort)
                .add("protocol", protocol)
                .add("srcMac", srcMac)
                .add("dstMac", dstMac)
                .add("statsInfo", statsInfo)
                .toString();
    }

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

    /**
     * Builder class of DefaultFlowInfo.
     */
    public static final class DefaultBuilder implements FlowInfo.Builder {

        private byte flowType;
        private DeviceId deviceId;
        private int inputInterfaceId;
        private int outputInterfaceId;
        private VlanId vlanId;
        private short vxlanId;
        private IpPrefix srcIp;
        private IpPrefix dstIp;
        private TpPort srcPort;
        private TpPort dstPort;
        private byte protocol;
        private MacAddress srcMac;
        private MacAddress dstMac;
        private StatsInfo statsInfo;

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

        @Override
        public Builder withDeviceId(DeviceId deviceId) {
            this.deviceId = deviceId;
            return this;
        }

        @Override
        public Builder withInputInterfaceId(int inputInterfaceId) {
            this.inputInterfaceId = inputInterfaceId;
            return this;
        }

        @Override
        public Builder withOutputInterfaceId(int outputInterfaceId) {
            this.outputInterfaceId = outputInterfaceId;
            return this;
        }

        @Override
        public Builder withVlanId(VlanId vlanId) {
            this.vlanId = vlanId;
            return this;
        }

        @Override
        public Builder withVxlanId(short vxlanId) {
            this.vxlanId = vxlanId;
            return this;
        }

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

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

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

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

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

        @Override
        public Builder withSrcMac(MacAddress srcMac) {
            this.srcMac = srcMac;
            return this;
        }

        @Override
        public Builder withDstMac(MacAddress dstMac) {
            this.dstMac = dstMac;
            return this;
        }

        @Override
        public Builder withStatsInfo(StatsInfo statsInfo) {
            this.statsInfo = statsInfo;
            return this;
        }

        @Override
        public FlowInfo build() {

            // TODO: need to check the null value for more properties
            checkNotNull(srcIp, "Source IP address cannot be null");
            checkNotNull(dstIp, "Destination IP address cannot be null");
            checkNotNull(statsInfo, "StatsInfo cannot be null");

            return new DefaultFlowInfo(flowType, deviceId, inputInterfaceId,
                    outputInterfaceId, vlanId, vxlanId, srcIp, dstIp, srcPort, dstPort,
                    protocol, srcMac, dstMac, statsInfo);
        }
    }
}
