/*
 * Copyright 2017-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.flow.criteria;

import com.google.common.annotations.Beta;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import org.onosproject.net.pi.runtime.PiExactFieldMatch;
import org.onosproject.net.pi.runtime.PiFieldMatch;
import org.onosproject.net.pi.runtime.PiHeaderFieldId;
import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
import org.onosproject.net.pi.runtime.PiRangeFieldMatch;
import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
import org.onosproject.net.pi.runtime.PiValidFieldMatch;

import java.util.Collection;
import java.util.Optional;
import java.util.StringJoiner;

import static com.google.common.base.Preconditions.checkArgument;
import static org.onlab.util.ImmutableByteSequence.copyFrom;

/**
 * Protocol-independent criterion.
 */
@Beta
public final class PiCriterion implements Criterion {

    private final ImmutableMap<PiHeaderFieldId, PiFieldMatch> fieldMatchMap;

    /**
     * Creates a new protocol-independent criterion for the given match fields.
     *
     * @param fieldMatchMap field match map
     */
    private PiCriterion(ImmutableMap<PiHeaderFieldId, PiFieldMatch> fieldMatchMap) {
        this.fieldMatchMap = fieldMatchMap;
    }

    /**
     * Returns all protocol-independent field matches defined by this criterion.
     *
     * @return collection of match parameters
     */
    public Collection<PiFieldMatch> fieldMatches() {
        return fieldMatchMap.values();
    }

    /**
     * If present, returns the field match associated with the given header field identifier.
     *
     * @param fieldId field identifier
     * @return optional field match
     */
    public Optional<PiFieldMatch> fieldMatch(PiHeaderFieldId fieldId) {
        return Optional.ofNullable(fieldMatchMap.get(fieldId));
    }

    @Override
    public Type type() {
        return Type.PROTOCOL_INDEPENDENT;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        PiCriterion that = (PiCriterion) o;
        return Objects.equal(fieldMatchMap, that.fieldMatchMap);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(fieldMatchMap);
    }

    @Override
    public String toString() {
        StringJoiner stringParams = new StringJoiner(", ", "{", "}");
        fieldMatchMap.forEach((key, value) -> stringParams.add(value.toString()));
        return stringParams.toString();
    }

    /**
     * Returns the PiCriterion builder.
     *
     * @return PiCriterion builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * PiCriterion Builder.
     */
    @Beta
    public static final class Builder {

        // Use map to guarantee that there's only one field match per field id.
        private final ImmutableMap.Builder<PiHeaderFieldId, PiFieldMatch> fieldMatchMapBuilder = ImmutableMap.builder();

        private Builder() {
            // ban constructor.
        }

        /**
         * Adds an exact field match for the given fieldId and value.
         *
         * @param fieldId protocol-independent header field Id
         * @param value   exact match value
         * @return this
         */
        public Builder matchExact(PiHeaderFieldId fieldId, short value) {
            fieldMatchMapBuilder.put(fieldId, new PiExactFieldMatch(fieldId, copyFrom(value)));
            return this;
        }

        /**
         * Adds an exact field match for the given fieldId and value.
         *
         * @param fieldId protocol-independent header field Id
         * @param value   exact match value
         * @return this
         */
        public Builder matchExact(PiHeaderFieldId fieldId, int value) {
            fieldMatchMapBuilder.put(fieldId, new PiExactFieldMatch(fieldId, copyFrom(value)));
            return this;
        }

        /**
         * Adds an exact field match for the given fieldId and value.
         *
         * @param fieldId protocol-independent header field Id
         * @param value   exact match value
         * @return this
         */
        public Builder matchExact(PiHeaderFieldId fieldId, long value) {
            fieldMatchMapBuilder.put(fieldId, new PiExactFieldMatch(fieldId, copyFrom(value)));
            return this;
        }

        /**
         * Adds an exact field match for the given fieldId and value.
         *
         * @param fieldId protocol-independent header field Id
         * @param value   exact match value
         * @return this
         */
        public Builder matchExact(PiHeaderFieldId fieldId, byte[] value) {
            fieldMatchMapBuilder.put(fieldId, new PiExactFieldMatch(fieldId, copyFrom(value)));
            return this;
        }

        /**
         * Adds a ternary field match for the given fieldId, value and mask.
         *
         * @param fieldId protocol-independent header field Id
         * @param value   ternary match value
         * @param mask    ternary match mask
         * @return this
         */
        public Builder matchTernary(PiHeaderFieldId fieldId, short value, short mask) {
            fieldMatchMapBuilder.put(fieldId, new PiTernaryFieldMatch(fieldId, copyFrom(value), copyFrom(mask)));
            return this;
        }

        /**
         * Adds a ternary field match for the given fieldId, value and mask.
         *
         * @param fieldId protocol-independent header field Id
         * @param value   ternary match value
         * @param mask    ternary match mask
         * @return this
         */
        public Builder matchTernary(PiHeaderFieldId fieldId, int value, int mask) {
            fieldMatchMapBuilder.put(fieldId, new PiTernaryFieldMatch(fieldId, copyFrom(value), copyFrom(mask)));
            return this;
        }

        /**
         * Adds a ternary field match for the given fieldId, value and mask.
         *
         * @param fieldId protocol-independent header field Id
         * @param value   ternary match value
         * @param mask    ternary match mask
         * @return this
         */
        public Builder matchTernary(PiHeaderFieldId fieldId, long value, long mask) {
            fieldMatchMapBuilder.put(fieldId, new PiTernaryFieldMatch(fieldId, copyFrom(value), copyFrom(mask)));
            return this;
        }

        /**
         * Adds a ternary field match for the given fieldId, value and mask.
         *
         * @param fieldId protocol-independent header field Id
         * @param value   ternary match value
         * @param mask    ternary match mask
         * @return this
         */
        public Builder matchTernary(PiHeaderFieldId fieldId, byte[] value, byte[] mask) {
            fieldMatchMapBuilder.put(fieldId, new PiTernaryFieldMatch(fieldId, copyFrom(value), copyFrom(mask)));
            return this;
        }

        /**
         * Adds a longest-prefix field match for the given fieldId, value and prefix length.
         *
         * @param fieldId      protocol-independent header field Id
         * @param value        lpm match value
         * @param prefixLength lpm match prefix length
         * @return this
         */
        public Builder matchLpm(PiHeaderFieldId fieldId, short value, int prefixLength) {
            fieldMatchMapBuilder.put(fieldId, new PiLpmFieldMatch(fieldId, copyFrom(value), prefixLength));
            return this;
        }

        /**
         * Adds a longest-prefix field match for the given fieldId, value and prefix length.
         *
         * @param fieldId      protocol-independent header field Id
         * @param value        lpm match value
         * @param prefixLength lpm match prefix length
         * @return this
         */
        public Builder matchLpm(PiHeaderFieldId fieldId, int value, int prefixLength) {
            fieldMatchMapBuilder.put(fieldId, new PiLpmFieldMatch(fieldId, copyFrom(value), prefixLength));
            return this;
        }

        /**
         * Adds a longest-prefix field match for the given fieldId, value and prefix length.
         *
         * @param fieldId      protocol-independent header field Id
         * @param value        lpm match value
         * @param prefixLength lpm match prefix length
         * @return this
         */
        public Builder matchLpm(PiHeaderFieldId fieldId, long value, int prefixLength) {
            fieldMatchMapBuilder.put(fieldId, new PiLpmFieldMatch(fieldId, copyFrom(value), prefixLength));
            return this;
        }

        /**
         * Adds a longest-prefix field match for the given fieldId, value and prefix length.
         *
         * @param fieldId      protocol-independent header field Id
         * @param value        lpm match value
         * @param prefixLength lpm match prefix length
         * @return this
         */
        public Builder matchLpm(PiHeaderFieldId fieldId, byte[] value, int prefixLength) {
            fieldMatchMapBuilder.put(fieldId, new PiLpmFieldMatch(fieldId, copyFrom(value), prefixLength));
            return this;
        }

        /**
         * Adds a valid field match for the given fieldId and flag.
         *
         * @param fieldId protocol-independent header field Id
         * @param flag    a boolean value
         * @return this
         */
        public Builder matchValid(PiHeaderFieldId fieldId, boolean flag) {
            fieldMatchMapBuilder.put(fieldId, new PiValidFieldMatch(fieldId, flag));
            return this;
        }

        /**
         * Adds a range field match for the given fieldId, low and high.
         *
         * @param fieldId protocol-independent header field Id
         * @param low     range match low value
         * @param high    range match high value
         * @return this
         */
        public Builder matchRange(PiHeaderFieldId fieldId, short low, short high) {
            fieldMatchMapBuilder.put(fieldId, new PiRangeFieldMatch(fieldId, copyFrom(low), copyFrom(high)));
            return this;
        }

        /**
         * Adds a range field match for the given fieldId, low and high.
         *
         * @param fieldId protocol-independent header field Id
         * @param low     range match low value
         * @param high    range match high value
         * @return this
         */
        public Builder matchRange(PiHeaderFieldId fieldId, int low, int high) {
            fieldMatchMapBuilder.put(fieldId, new PiRangeFieldMatch(fieldId, copyFrom(low), copyFrom(high)));
            return this;
        }

        /**
         * Adds a range field match for the given fieldId, low and high.
         *
         * @param fieldId protocol-independent header field Id
         * @param low     range match low value
         * @param high    range match high value
         * @return this
         */
        public Builder matchRange(PiHeaderFieldId fieldId, long low, long high) {
            fieldMatchMapBuilder.put(fieldId, new PiRangeFieldMatch(fieldId, copyFrom(low), copyFrom(high)));
            return this;
        }

        /**
         * Adds a range field match for the given fieldId, low and high.
         *
         * @param fieldId protocol-independent header field Id
         * @param low     range match low value
         * @param high    range match high value
         * @return this
         */
        public Builder matchRange(PiHeaderFieldId fieldId, byte[] low, byte[] high) {
            fieldMatchMapBuilder.put(fieldId, new PiRangeFieldMatch(fieldId, copyFrom(low), copyFrom(high)));
            return this;
        }

        /**
         * Builds a PiCriterion.
         *
         * @return PiCriterion
         */
        public PiCriterion build() {
            ImmutableMap<PiHeaderFieldId, PiFieldMatch> fieldMatchMap = fieldMatchMapBuilder.build();
            checkArgument(fieldMatchMap.size() > 0, "Cannot build PI criterion with 0 field matches");
            return new PiCriterion(fieldMatchMap);
        }
    }
}