/*
 * 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.model.PiMatchFieldId;
import org.onosproject.net.pi.runtime.PiExactFieldMatch;
import org.onosproject.net.pi.runtime.PiFieldMatch;
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<PiMatchFieldId, PiFieldMatch> fieldMatchMap;

    /**
     * Creates a new protocol-independent criterion for the given match fields.
     *
     * @param fieldMatchMap field match map
     */
    private PiCriterion(ImmutableMap<PiMatchFieldId, 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(PiMatchFieldId 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<PiMatchFieldId, 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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(PiMatchFieldId 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<PiMatchFieldId, PiFieldMatch> fieldMatchMap = fieldMatchMapBuilder.build();
            checkArgument(fieldMatchMap.size() > 0, "Cannot build PI criterion with 0 field matches");
            return new PiCriterion(fieldMatchMap);
        }
    }
}
