/*
 * Copyright 2021-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.net.behaviour.upf;

import com.google.common.annotations.Beta;
import org.onlab.packet.Ip4Address;

import java.util.Objects;

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

/**
 * A structure representing the UE Termination in the downlink direction on the
 * UPF-programmable device.
 * Provides means to configure the traffic behavior (e.g. set Traffic Class, GTP TEID, or QFI).
 */
@Beta
public final class UpfTerminationDownlink implements UpfEntity {
    // Match Keys
    private final Ip4Address ueSessionId; // UE Session ID, use UE IP address to uniquely identify a session.
    // Action parameters
    private final Integer ctrId;  // Counter ID unique to this UPF Termination Rule
    private final Byte trafficClass;
    private final Integer teid;  // Tunnel Endpoint Identifier
    private final Byte qfi; // QoS Flow Identifier
    private final boolean dropping;

    private UpfTerminationDownlink(Ip4Address ueSessionId, Integer ctrId, Byte trafficClass,
                                   Integer teid, Byte qfi, boolean dropping) {
        this.ueSessionId = ueSessionId;
        this.ctrId = ctrId;
        this.trafficClass = trafficClass;
        this.teid = teid;
        this.qfi = qfi;
        this.dropping = dropping;
    }

    public static Builder builder() {
        return new Builder();
    }

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

        // Safe comparisons between potentially null objects
        return this.dropping == that.dropping &&
                Objects.equals(this.ueSessionId, that.ueSessionId) &&
                Objects.equals(this.ctrId, that.ctrId) &&
                Objects.equals(this.trafficClass, that.trafficClass) &&
                Objects.equals(this.teid, that.teid) &&
                Objects.equals(this.qfi, that.qfi);
    }

    @Override
    public int hashCode() {
        return Objects.hash(ueSessionId, ctrId, trafficClass, teid, qfi, dropping);
    }

    /**
     * Get UE Session ID associated with UPF Termination rule.
     *
     * @return UE Session ID
     */
    public Ip4Address ueSessionId() {
        return ueSessionId;
    }

    /**
     * Get PDR Counter ID associated with UPF Termination rule.
     *
     * @return PDR counter cell ID
     */
    public Integer counterId() {
        return ctrId;
    }

    /**
     * Get Traffic Class set by this UPF Termination rule.
     *
     * @return Traffic Class
     */
    public Byte trafficClass() {
        return trafficClass;
    }

    /**
     * Get GTP TEID set by this UPF Termination rule.
     *
     * @return GTP tunnel ID
     */
    public Integer teid() {
        return teid;
    }

    /**
     * Get QoS Flow Identifier set by this UPF Termination rule.
     *
     * @return QoS Flow Identifier
     */
    public Byte qfi() {
        return qfi;
    }

    /**
     * True if this UPF Termination needs to drop traffic.
     *
     * @return true if the UPF Termination needs dropping.
     */
    public boolean needsDropping() {
        return dropping;
    }

    @Override
    public UpfEntityType type() {
        return UpfEntityType.TERMINATION_DOWNLINK;
    }

    @Override
    public String toString() {
        return "TerminationDL{" + matchString() + "->" + actionString() + "}";
    }

    private String matchString() {
        return "Match(ue_addr=" + this.ueSessionId() + ")";
    }

    private String actionString() {
        return "(TEID=" + this.teid() +
                ", CTR_ID=" + this.counterId() +
                ", QFI=" + this.qfi() +
                ", TC=" + this.trafficClass() +
                ")";
    }

    public static class Builder {
        private Ip4Address ueSessionId = null;
        private Integer ctrId = null;
        private Byte trafficClass = null;
        private Integer teid = null;
        private Byte qfi = null;
        private boolean drop = false;

        public Builder() {

        }

        /**
         * Set the ID of the UE session.
         *
         * @param ueSessionId UE session ID
         * @return This builder object
         */
        public Builder withUeSessionId(Ip4Address ueSessionId) {
            this.ueSessionId = ueSessionId;
            return this;
        }

        /**
         * Set the dataplane counter cell ID.
         *
         * @param ctrId PDR counter cell ID
         * @return This builder object
         */
        public Builder withCounterId(int ctrId) {
            this.ctrId = ctrId;
            return this;
        }

        /**
         * Set the Traffic Class.
         *
         * @param trafficClass Traffic Class
         * @return This builder object
         */
        public Builder withTrafficClass(byte trafficClass) {
            this.trafficClass = trafficClass;
            return this;
        }

        /**
         * Set the identifier of the unidirectional GTP tunnel that should be used for the UE Session.
         *
         * @param teid tunnel ID
         * @return This builder object
         */
        public Builder withTeid(Integer teid) {
            this.teid = teid;
            return this;
        }

        /**
         * Set the QoS Flow Identifier.
         *
         * @param qfi GTP Tunnel QFI
         * @return This builder object
         */
        public Builder withQfi(byte qfi) {
            this.qfi = qfi;
            return this;
        }

        /**
         * Sets whether to drop downlink UPF termination traffic or not.
         *
         * @param drop True if request to buffer, false otherwise
         * @return This builder object
         */
        public Builder needsDropping(boolean drop) {
            this.drop = drop;
            return this;
        }


        public UpfTerminationDownlink build() {
            // Match fields must be provided
            checkNotNull(ueSessionId, "UE session ID must be provided");

            checkNotNull(ctrId, "Counter ID must be provided");
            // TODO: should we verify that when dropping no other fields are provided
            return new UpfTerminationDownlink(
                    this.ueSessionId, this.ctrId, this.trafficClass, this.teid,
                    this.qfi, this.drop
            );
        }

    }

}
