/*
 * 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;

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

    public static final PiMatchKey EMPTY = builder().build();

    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();
            return new PiMatchKey(fieldMatches);
        }
    }
}
