/*
 * 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.p4runtime.model;

import com.google.common.collect.ImmutableMap;
import org.onosproject.net.pi.model.PiActionId;
import org.onosproject.net.pi.model.PiActionModel;
import org.onosproject.net.pi.model.PiActionProfileModel;
import org.onosproject.net.pi.model.PiCounterId;
import org.onosproject.net.pi.model.PiCounterModel;
import org.onosproject.net.pi.model.PiMatchFieldId;
import org.onosproject.net.pi.model.PiMatchFieldModel;
import org.onosproject.net.pi.model.PiMeterId;
import org.onosproject.net.pi.model.PiMeterModel;
import org.onosproject.net.pi.model.PiTableId;
import org.onosproject.net.pi.model.PiTableModel;
import org.onosproject.net.pi.model.PiTableType;

import java.util.Collection;
import java.util.Objects;
import java.util.Optional;

/**
 * Implementation of PiTableModel for P4Runtime.
 */
final class P4TableModel implements PiTableModel {

    private final PiTableId id;
    private final PiTableType tableType;
    private final PiActionProfileModel actionProfile;
    private final long maxSize;
    private final ImmutableMap<PiCounterId, PiCounterModel> counters;
    private final ImmutableMap<PiMeterId, PiMeterModel> meters;
    private final boolean supportAging;
    private final ImmutableMap<PiMatchFieldId, PiMatchFieldModel> matchFields;
    private final ImmutableMap<PiActionId, PiActionModel> actions;
    private final PiActionModel defaultAction;
    private final boolean hasDefaultMutableParams;

    P4TableModel(PiTableId id, PiTableType tableType,
                        PiActionProfileModel actionProfile, long maxSize,
                        ImmutableMap<PiCounterId, PiCounterModel> counters,
                        ImmutableMap<PiMeterId, PiMeterModel> meters, boolean supportAging,
                        ImmutableMap<PiMatchFieldId, PiMatchFieldModel> matchFields,
                        ImmutableMap<PiActionId, PiActionModel> actions,
                        PiActionModel defaultAction, boolean hasDefaultMutableParams) {
        this.id = id;
        this.tableType = tableType;
        this.actionProfile = actionProfile;
        this.maxSize = maxSize;
        this.counters = counters;
        this.meters = meters;
        this.supportAging = supportAging;
        this.matchFields = matchFields;
        this.actions = actions;
        this.defaultAction = defaultAction;
        this.hasDefaultMutableParams = hasDefaultMutableParams;
    }

    @Override
    public PiTableId id() {
        return id;
    }

    @Override
    public PiTableType tableType() {
        return tableType;
    }

    @Override
    public PiActionProfileModel actionProfile() {
        return actionProfile;
    }

    @Override
    public long maxSize() {
        return maxSize;
    }

    @Override
    public Collection<PiCounterModel> counters() {
        return counters.values();
    }

    @Override
    public Collection<PiMeterModel> meters() {
        return meters.values();
    }

    @Override
    public boolean supportsAging() {
        return supportAging;
    }

    @Override
    public Collection<PiMatchFieldModel> matchFields() {
        return matchFields.values();
    }

    @Override
    public Collection<PiActionModel> actions() {
        return actions.values();
    }

    @Override
    public Optional<PiActionModel> defaultAction() {
        return Optional.ofNullable(defaultAction);
    }

    @Override
    public boolean hasDefaultMutableParams() {
        return hasDefaultMutableParams;
    }

    @Override
    public Optional<PiActionModel> action(PiActionId actionId) {
        return Optional.ofNullable(actions.get(actionId));
    }

    @Override
    public Optional<PiMatchFieldModel> matchField(PiMatchFieldId matchFieldId) {
        return Optional.ofNullable(matchFields.get(matchFieldId));
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, tableType, actionProfile, maxSize, counters,
                            meters, supportAging, matchFields, actions,
                            defaultAction, hasDefaultMutableParams);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        final P4TableModel other = (P4TableModel) obj;
        return Objects.equals(this.id, other.id)
                && Objects.equals(this.tableType, other.tableType)
                && Objects.equals(this.actionProfile, other.actionProfile)
                && Objects.equals(this.maxSize, other.maxSize)
                && Objects.equals(this.counters, other.counters)
                && Objects.equals(this.meters, other.meters)
                && Objects.equals(this.supportAging, other.supportAging)
                && Objects.equals(this.matchFields, other.matchFields)
                && Objects.equals(this.actions, other.actions)
                && Objects.equals(this.defaultAction, other.defaultAction)
                && Objects.equals(this.hasDefaultMutableParams, other.hasDefaultMutableParams);
    }
}
