/*
 * 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.pi.runtime;

import com.google.common.annotations.Beta;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;

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

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

/**
 * Representation of all field matches of an entry of a match+action table of a protocol-independent pipeline.
 */
@Beta
public final class PiMatchKey {

    private final ImmutableMap<PiHeaderFieldId, PiFieldMatch> fieldMatches;

    private PiMatchKey(ImmutableMap<PiHeaderFieldId, PiFieldMatch> fieldMatches) {
        this.fieldMatches = fieldMatches;
    }

    /**
     * Returns the collection of field matches of this match key.
     *
     * @return collection of field matches
     */
    public Collection<PiFieldMatch> fieldMatches() {
        return fieldMatches.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(fieldMatches.get(fieldId));
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof PiMatchKey)) {
            return false;
        }
        PiMatchKey that = (PiMatchKey) o;
        return Objects.equal(fieldMatches, that.fieldMatches);
    }

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

    @Override
    public String toString() {
        StringJoiner stringFieldMatches = new StringJoiner(", ", "{", "}");
        this.fieldMatches.values().forEach(f -> stringFieldMatches.add(f.toString()));
        return stringFieldMatches.toString();
    }

    /**
     * Returns a new builder of match keys.
     *
     * @return match key builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Builder of match keys.
     */
    public static final class Builder {

        private final ImmutableMap.Builder<PiHeaderFieldId, PiFieldMatch> fieldMatchesBuilder = ImmutableMap.builder();

        private Builder() {
            // hides constructor.
        }

        /**
         * Adds one field match to this match key.
         *
         * @param fieldMatch field match
         * @return this
         */
        public Builder addFieldMatch(PiFieldMatch fieldMatch) {
            this.fieldMatchesBuilder.put(fieldMatch.fieldId(), fieldMatch);
            return this;
        }

        /**
         * Adds many field matches to this match key.
         *
         * @param fieldMatches collection of field matches
         * @return this
         */
        public Builder addFieldMatches(Collection<PiFieldMatch> fieldMatches) {
            fieldMatches.forEach(this::addFieldMatch);
            return this;
        }

        /**
         * Creates a new match key.
         *
         * @return match key
         */
        public PiMatchKey build() {
            ImmutableMap<PiHeaderFieldId, PiFieldMatch> fieldMatches = fieldMatchesBuilder.build();
            checkArgument(fieldMatches.size() > 0, "Field matches cannot be empty");
            return new PiMatchKey(fieldMatches);
        }
    }
}
