/*
 * 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 org.onlab.packet.Ip4Address;
import org.onlab.util.ImmutableByteSequence;

import java.util.Objects;

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

/**
 * A single Packet Detection Rule (PDR), an entity described in the 3GPP
 * specifications (although that does not mean that this class is 3GPP
 * compliant). An instance of this class will be generated by a logical switch
 * write request to the database-style PDR P4 table, and the resulting instance
 * should contain all the information needed to reproduce that logical switch
 * PDR in the event of a client read request. The instance should also contain
 * sufficient information (or expose the means to retrieve such information) to
 * generate the corresponding dataplane forwarding state that implements the PDR.
 */
public final class PacketDetectionRule {
    // Match keys
    private final Ip4Address ueAddr;  // The UE IP address that this PDR matches on
    private final ImmutableByteSequence teid;  // The Tunnel Endpoint ID that this PDR matches on
    private final Ip4Address tunnelDst;  // The tunnel destination address that this PDR matches on
    // Action parameters
    private final ImmutableByteSequence sessionId;  // The ID of the PFCP session that created this PDR
    private final Integer ctrId;  // Counter ID unique to this PDR
    private final Integer farId;  // The PFCP session-local ID of the FAR that should apply after this PDR hits
    private final Type type;

    private final Byte qfi; // QoS Flow Identifier of this PDR
    private final boolean qfiPush; // True when QFI should be pushed to the packet
    private final boolean qfiMatch; // True when QFI should be matched

    private static final int SESSION_ID_BITWIDTH = 96;

    private PacketDetectionRule(ImmutableByteSequence sessionId, Integer ctrId,
                                Integer farId, Ip4Address ueAddr, Byte qfi,
                                ImmutableByteSequence teid, Ip4Address tunnelDst,
                                Type type, boolean qfiPush, boolean qfiMatch) {
        this.ueAddr = ueAddr;
        this.teid = teid;
        this.tunnelDst = tunnelDst;
        this.sessionId = sessionId;
        this.ctrId = ctrId;
        this.farId = farId;
        this.qfi = qfi;
        this.type = type;
        this.qfiPush = qfiPush;
        this.qfiMatch = qfiMatch;
    }

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

    /**
     * Return a string representing the match conditions of this PDR.
     *
     * @return a string representing the PDR match conditions
     */
    public String matchString() {
        if (matchesEncapped()) {
            return matchQfi() ?
                    String.format("Match(Dst=%s, TEID=%s, QFI=%s)", tunnelDest(), teid(), qfi()) :
                    String.format("Match(Dst=%s, TEID=%s)", tunnelDest(), teid());
        } else {
            return String.format("Match(Dst=%s, !GTP)", ueAddress());
        }
    }

    @Override
    public String toString() {
        String actionParams = "";
        if (hasActionParameters()) {
            actionParams = hasQfi() && !matchQfi() ?
                    String.format("SEID=%s, FAR=%d, CtrIdx=%d, QFI=%s",
                                  sessionId.toString(), farId, ctrId, qfi) :
                    String.format("SEID=%s, FAR=%d, CtrIdx=%d",
                                  sessionId.toString(), farId, ctrId);
            actionParams = pushQfi() ? String.format("%s, QFI_PUSH", actionParams) : actionParams;
        }

        return String.format("PDR{%s -> LoadParams(%s)}",
                             matchString(), actionParams);
    }

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

        // Safe comparisons between potentially null objects
        return (this.type.equals(that.type) &&
                Objects.equals(this.teid, that.teid) &&
                Objects.equals(this.tunnelDst, that.tunnelDst) &&
                Objects.equals(this.ueAddr, that.ueAddr) &&
                Objects.equals(this.ctrId, that.ctrId) &&
                Objects.equals(this.sessionId, that.sessionId) &&
                Objects.equals(this.farId, that.farId) &&
                Objects.equals(this.qfi, that.qfi) &&
                Objects.equals(this.qfiPush, that.qfiPush) &&
                Objects.equals(this.qfiMatch, that.qfiMatch));
    }

    @Override
    public int hashCode() {
        return Objects.hash(ueAddr, teid, tunnelDst, sessionId, ctrId, farId,
                            qfi, type);
    }

    /**
     * Instances created as a result of DELETE write requests will not have
     * action parameters, only match keys. This method should be used to avoid
     * null pointer exceptions in those instances.
     *
     * @return true if this instance has PDR action parameters, false otherwise.
     */
    public boolean hasActionParameters() {
        return type == Type.MATCH_ENCAPPED || type == Type.MATCH_UNENCAPPED;
    }

    /**
     * Return a new instance of this PDR with the action parameters stripped,
     * leaving only the match keys.
     *
     * @return a new PDR with only match keys
     */
    public PacketDetectionRule withoutActionParams() {
        if (matchesEncapped()) {
            PacketDetectionRule.Builder pdrBuilder = PacketDetectionRule.builder()
                    .withTeid(teid)
                    .withTunnelDst(tunnelDst);
            if (this.hasQfi() && this.matchQfi()) {
                pdrBuilder.withQfiMatch();
                pdrBuilder.withQfi(qfi);
            }
            return pdrBuilder.build();
        } else {
            return PacketDetectionRule.builder()
                    .withUeAddr(ueAddr).build();
        }
    }

    /**
     * True if this PDR matches on packets received with a GTP header, and false
     * otherwise.
     *
     * @return true if the PDR matches only encapsulated packets
     */
    public boolean matchesEncapped() {
        return type == Type.MATCH_ENCAPPED ||
                type == Type.MATCH_ENCAPPED_NO_ACTION;
    }

    /**
     * True if this PDR matches on packets received without a GTP header, and
     * false otherwise.
     *
     * @return true if the PDR matches only un-encapsulated packets
     */
    public boolean matchesUnencapped() {
        return type == Type.MATCH_UNENCAPPED ||
                type == Type.MATCH_UNENCAPPED_NO_ACTION;
    }

    /**
     * Get the ID of the PFCP session that produced this PDR.
     *
     * @return PFCP session ID
     */
    public ImmutableByteSequence sessionId() {
        return sessionId;
    }

    /**
     * Get the UE IP address that this PDR matches on.
     *
     * @return UE IP address
     */
    public Ip4Address ueAddress() {
        return ueAddr;
    }

    /**
     * Get the identifier of the GTP tunnel that this PDR matches on.
     *
     * @return GTP tunnel ID
     */
    public ImmutableByteSequence teid() {
        return teid;
    }

    /**
     * Get the destination IP of the GTP tunnel that this PDR matches on.
     *
     * @return GTP tunnel destination IP
     */
    public Ip4Address tunnelDest() {
        return tunnelDst;
    }

    /**
     * Get the dataplane PDR counter cell ID that this PDR is assigned.
     *
     * @return PDR counter cell ID
     */
    public int counterId() {
        return ctrId;
    }

    /**
     * Get the PFCP session-local ID of the far that should apply to packets
     * that this PDR matches.
     *
     * @return PFCP session-local FAR ID
     */
    public int farId() {
        return farId;
    }

    /**
     * Get the QoS Flow Identifier for this PDR.
     *
     * @return QoS Flow Identifier
     */
    public byte qfi() {
        return qfi;
    }

    /**
     * Returns whether QFi should be pushed to the packet.
     *
     * @return True if the QFI should be pushed to the packet, false otherwise
     */
    public boolean pushQfi() {
        return qfiPush;
    }

    /**
     * Returns whether QFI should be matched on the packet or not.
     *
     * @return True if QFI should be matched on the packet, false otherwise
     */
    public boolean matchQfi() {
        return qfiMatch;
    }

    /**
     * Checks if the PDR has a QFI to match upon or to push on the packet.
     *
     * @return True if the PDR has a QFI, false otherwise
     */
    public boolean hasQfi() {
        return qfi != null;
    }

    private enum Type {
        /**
         * Match on packets that are encapsulated in a GTP tunnel.
         */
        MATCH_ENCAPPED,
        /**
         * Match on packets that are not encapsulated in a GTP tunnel.
         */
        MATCH_UNENCAPPED,
        /**
         * For PDRs that match on encapsulated packets but do not yet have any
         * action parameters set.
         * These are usually built in the context of P4Runtime DELETE write requests.
         */
        MATCH_ENCAPPED_NO_ACTION,
        /**
         * For PDRs that match on unencapsulated packets but do not yet have any
         * action parameters set.
         * These are usually built in the context of P4Runtime DELETE write requests.
         */
        MATCH_UNENCAPPED_NO_ACTION
    }

    public static class Builder {
        private ImmutableByteSequence sessionId = null;
        private Integer ctrId = null;
        private Integer localFarId = null;
        private Integer schedulingPriority = null;
        private Ip4Address ueAddr = null;
        private ImmutableByteSequence teid = null;
        private Ip4Address tunnelDst = null;
        private Byte qfi = null;
        private boolean qfiPush = false;
        private boolean qfiMatch = false;

        public Builder() {

        }

        /**
         * Set the ID of the PFCP session that produced this PDR.
         *
         * @param sessionId PFCP session ID
         * @return This builder object
         */
        public Builder withSessionId(ImmutableByteSequence sessionId) {
            this.sessionId = sessionId;
            return this;
        }

        /**
         * Set the ID of the PFCP session that produced this PDR.
         *
         * @param sessionId PFCP session ID
         * @return This builder object
         */
        public Builder withSessionId(long sessionId) {
            try {
                this.sessionId = ImmutableByteSequence.copyFrom(sessionId)
                        .fit(SESSION_ID_BITWIDTH);
            } catch (ImmutableByteSequence.ByteSequenceTrimException e) {
                // This error is literally impossible
            }
            return this;
        }

        /**
         * Set the UE IP address that this PDR matches on.
         *
         * @param ueAddr UE IP address
         * @return This builder object
         */
        public Builder withUeAddr(Ip4Address ueAddr) {
            this.ueAddr = ueAddr;
            return this;
        }

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


        /**
         * Set the PFCP session-local ID of the far that should apply to packets that this PDR matches.
         *
         * @param localFarId PFCP session-local FAR ID
         * @return This builder object
         */
        public Builder withLocalFarId(int localFarId) {
            this.localFarId = localFarId;
            return this;
        }

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

        /**
         * The QoS Flow Identifier should be pushed to the packet.
         * This is valid for downstream packets and for 5G traffic only.
         *
         * @return This builder object
         */
        public Builder withQfiPush() {
            this.qfiPush = true;
            return this;
        }

        /**
         * The QoS Flow Identifier should be matched to the packet.
         * This is valid for upstream packets and for 5G traffic only.
         *
         * @return This builder object
         */
        public Builder withQfiMatch() {
            this.qfiMatch = true;
            return this;
        }

        /**
         * Set the identifier of the GTP tunnel that this PDR matches on.
         *
         * @param teid GTP tunnel ID
         * @return This builder object
         */
        public Builder withTeid(int teid) {
            this.teid = ImmutableByteSequence.copyFrom(teid);
            return this;
        }

        /**
         * Set the identifier of the GTP tunnel that this PDR matches on.
         *
         * @param teid GTP tunnel ID
         * @return This builder object
         */
        public Builder withTeid(ImmutableByteSequence teid) {
            this.teid = teid;
            return this;
        }

        /**
         * Set the destination IP of the GTP tunnel that this PDR matches on.
         *
         * @param tunnelDst GTP tunnel destination IP
         * @return This builder object
         */
        public Builder withTunnelDst(Ip4Address tunnelDst) {
            this.tunnelDst = tunnelDst;
            return this;
        }

        /**
         * Set the tunnel ID and destination IP of the GTP tunnel that this PDR matches on.
         *
         * @param teid      GTP tunnel ID
         * @param tunnelDst GTP tunnel destination IP
         * @return This builder object
         */
        public Builder withTunnel(ImmutableByteSequence teid, Ip4Address tunnelDst) {
            this.teid = teid;
            this.tunnelDst = tunnelDst;
            return this;
        }

        /**
         * Set the tunnel ID, destination IP and QFI of the GTP tunnel that this PDR matches on.
         *
         * @param teid      GTP tunnel ID
         * @param tunnelDst GTP tunnel destination IP
         * @param qfi       GTP QoS Flow Identifier
         * @return This builder object
         */
        public Builder withTunnel(ImmutableByteSequence teid, Ip4Address tunnelDst, byte qfi) {
            this.teid = teid;
            this.tunnelDst = tunnelDst;
            this.qfi = qfi;
            return this;
        }

        public PacketDetectionRule build() {
            // Some match keys are required.
            checkArgument(
                    (ueAddr != null && teid == null && tunnelDst == null) ||
                            (ueAddr == null && teid != null && tunnelDst != null),
                    "Either a UE address or a TEID and Tunnel destination must be provided, but not both.");
            // Action parameters are optional but must be all provided together if they are provided
            checkArgument(
                    (sessionId != null && ctrId != null && localFarId != null) ||
                            (sessionId == null && ctrId == null && localFarId == null),
                    "PDR action parameters must be provided together or not at all.");
            checkArgument(!qfiPush || !qfiMatch,
                          "Either match of push QFI can be true, not both.");
            checkArgument(!qfiPush || qfi != null,
                          "A QFI must be provided when pushing QFI to the packet.");
            checkArgument(!qfiMatch || qfi != null,
                          "A QFI must be provided when matching QFI on the packet.");
            Type type;
            if (teid != null) {
                if (sessionId != null) {
                    type = Type.MATCH_ENCAPPED;
                } else {
                    type = Type.MATCH_ENCAPPED_NO_ACTION;
                }
            } else {
                if (sessionId != null) {
                    type = Type.MATCH_UNENCAPPED;
                } else {
                    type = Type.MATCH_UNENCAPPED_NO_ACTION;
                }
            }
            return new PacketDetectionRule(sessionId, ctrId, localFarId, ueAddr,
                                           qfi, teid, tunnelDst, type,
                                           qfiPush, qfiMatch);
        }
    }
}
