/*
 * 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.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.testing.EqualsTester;
import org.junit.Test;
import org.onosproject.net.pi.model.PiActionId;
import org.onosproject.net.pi.model.PiActionModel;
import org.onosproject.net.pi.model.PiActionParamId;
import org.onosproject.net.pi.model.PiActionParamModel;
import org.onosproject.net.pi.model.PiActionProfileId;
import org.onosproject.net.pi.model.PiActionProfileModel;
import org.onosproject.net.pi.model.PiControlMetadataId;
import org.onosproject.net.pi.model.PiControlMetadataModel;
import org.onosproject.net.pi.model.PiCounterId;
import org.onosproject.net.pi.model.PiCounterModel;
import org.onosproject.net.pi.model.PiCounterType;
import org.onosproject.net.pi.model.PiMatchFieldId;
import org.onosproject.net.pi.model.PiMatchFieldModel;
import org.onosproject.net.pi.model.PiMatchType;
import org.onosproject.net.pi.model.PiMeterId;
import org.onosproject.net.pi.model.PiMeterModel;
import org.onosproject.net.pi.model.PiMeterType;
import org.onosproject.net.pi.model.PiPacketOperationModel;
import org.onosproject.net.pi.model.PiPacketOperationType;
import org.onosproject.net.pi.model.PiPipelineModel;
import org.onosproject.net.pi.model.PiRegisterId;
import org.onosproject.net.pi.model.PiRegisterModel;
import org.onosproject.net.pi.model.PiTableId;
import org.onosproject.net.pi.model.PiTableModel;
import org.onosproject.net.pi.model.PiTableType;

import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;

/**
 * Unit tests for P4PipelineModel class.
 */
public class P4PipelineModelTest {

    /* Action Profiles */
    private static final PiActionProfileId PI_ACTION_PROFILE_ID_1 = PiActionProfileId.of("Action1");
    private static final PiActionProfileId PI_ACTION_PROFILE_ID_2 = PiActionProfileId.of("Action2");

    private static final PiTableId ACTION_PI_TABLE_ID_1 = PiTableId.of("ActionTable1");
    private static final PiTableId ACTION_PI_TABLE_ID_2 = PiTableId.of("ActionTable2");

    private static final ImmutableSet<PiTableId> ACTION_TABLES_1 = new ImmutableSet.Builder<PiTableId>()
            .add(ACTION_PI_TABLE_ID_1)
            .build();

    private static final ImmutableSet<PiTableId> ACTION_TABLES_2 = new ImmutableSet.Builder<PiTableId>()
            .add(ACTION_PI_TABLE_ID_2)
            .build();

    private static final boolean ACTION_HAS_SELECTOR_1 = true;
    private static final boolean ACTION_HAS_SELECTOR_2 = false;

    private static final long ACTION_MAX_SIZE_1 = 100;
    private static final long ACTION_MAX_SIZE_2 = 200;

    private static final int ACTION_MAX_GROUP_SIZE_1 = 10;
    private static final int ACTION_MAX_GROUP_SIZE_2 = 20;

    private static final PiActionProfileModel P4_ACTION_PROFILE_MODEL_1 =
            new P4ActionProfileModel(PI_ACTION_PROFILE_ID_1, ACTION_TABLES_1,
                                     ACTION_HAS_SELECTOR_1, ACTION_MAX_SIZE_1,
                                     ACTION_MAX_GROUP_SIZE_1);
    private static final PiActionProfileModel P4_ACTION_PROFILE_MODEL_2 =
            new P4ActionProfileModel(PI_ACTION_PROFILE_ID_2, ACTION_TABLES_2,
                                     ACTION_HAS_SELECTOR_2, ACTION_MAX_SIZE_2,
                                     ACTION_MAX_GROUP_SIZE_2);

    /* Counters */
    private static final PiCounterId PI_COUNTER_ID_1 = PiCounterId.of("Counter1");
    private static final PiCounterId PI_COUNTER_ID_2 = PiCounterId.of("Counter2");

    private static final PiCounterType PI_COUNTER_TYPE_1 = PiCounterType.DIRECT;
    private static final PiCounterType PI_COUNTER_TYPE_2 = PiCounterType.INDIRECT;

    private static final PiCounterModel.Unit COUNTER_UNIT_BYTES = P4CounterModel.Unit.BYTES;
    private static final PiCounterModel.Unit COUNTER_UNIT_PACKETS = P4CounterModel.Unit.PACKETS;

    private static final PiTableId COUNTER_PI_TABLE_ID_1 = PiTableId.of("CounterTable1");
    private static final PiTableId COUNTER_PI_TABLE_ID_2 = PiTableId.of("CounterTable2");

    private static final long COUNTER_SIZE_1 = 1000;
    private static final long COUNTER_SIZE_2 = 2000;

    private static final PiCounterModel P4_COUNTER_MODEL_1 =
            new P4CounterModel(PI_COUNTER_ID_1, PI_COUNTER_TYPE_1,
                               COUNTER_UNIT_BYTES, COUNTER_PI_TABLE_ID_1, COUNTER_SIZE_1);
    private static final PiCounterModel P4_COUNTER_MODEL_2 =
            new P4CounterModel(PI_COUNTER_ID_2, PI_COUNTER_TYPE_2,
                               COUNTER_UNIT_PACKETS, COUNTER_PI_TABLE_ID_2, COUNTER_SIZE_2);

    private static final ImmutableMap<PiCounterId, PiCounterModel> COUNTERS_1 =
            new ImmutableMap.Builder<PiCounterId, PiCounterModel>()
                    .put(PI_COUNTER_ID_1, P4_COUNTER_MODEL_1)
                    .build();
    private static final ImmutableMap<PiCounterId, PiCounterModel> COUNTERS_2 =
            new ImmutableMap.Builder<PiCounterId, PiCounterModel>()
                    .put(PI_COUNTER_ID_2, P4_COUNTER_MODEL_2)
                    .build();

    /* Meters */
    private static final PiMeterId PI_METER_ID_1 = PiMeterId.of("Meter1");
    private static final PiMeterId PI_METER_ID_2 = PiMeterId.of("Meter2");

    private static final PiMeterType PI_METER_TYPE_1 = PiMeterType.DIRECT;
    private static final PiMeterType PI_METER_TYPE_2 = PiMeterType.INDIRECT;

    private static final PiMeterModel.Unit METER_UNIT_BYTES = P4MeterModel.Unit.BYTES;
    private static final PiMeterModel.Unit METER_UNIT_PACKETS = P4MeterModel.Unit.PACKETS;

    private static final PiTableId METER_PI_TABLE_ID_1 = PiTableId.of("MeterTable1");
    private static final PiTableId METER_PI_TABLE_ID_2 = PiTableId.of("MeterTable2");

    private static final long METER_SIZE_1 = 1000;
    private static final long METER_SIZE_2 = 2000;

    private static final PiMeterModel P4_METER_MODEL_1 =
            new P4MeterModel(PI_METER_ID_1, PI_METER_TYPE_1, METER_UNIT_BYTES, METER_PI_TABLE_ID_1, METER_SIZE_1);
    private static final PiMeterModel P4_METER_MODEL_2 =
            new P4MeterModel(PI_METER_ID_2, PI_METER_TYPE_2, METER_UNIT_PACKETS, METER_PI_TABLE_ID_2, METER_SIZE_2);

    private static final ImmutableMap<PiMeterId, PiMeterModel> METERS_1 =
            new ImmutableMap.Builder<PiMeterId, PiMeterModel>()
                    .put(PI_METER_ID_1, P4_METER_MODEL_1)
                    .build();
    private static final ImmutableMap<PiMeterId, PiMeterModel> METERS_2 =
            new ImmutableMap.Builder<PiMeterId, PiMeterModel>()
                    .put(PI_METER_ID_2, P4_METER_MODEL_2)
                    .build();

    /* Registers */
    private static final PiRegisterId PI_REGISTER_ID_1 = PiRegisterId.of("Register1");
    private static final PiRegisterId PI_REGISTER_ID_2 = PiRegisterId.of("Register2");

    private static final long REGISTER_SIZE_1 = 1000;
    private static final long REGISTER_SIZE_2 = 2000;

    private static final P4RegisterModel P4_REGISTER_MODEL_1 = new P4RegisterModel(PI_REGISTER_ID_1, REGISTER_SIZE_1);
    private static final P4RegisterModel P4_REGISTER_MODEL_2 = new P4RegisterModel(PI_REGISTER_ID_2, REGISTER_SIZE_2);

    private static final ImmutableMap<PiRegisterId, PiRegisterModel> REGISTERS_1 =
            new ImmutableMap.Builder<PiRegisterId, PiRegisterModel>()
                    .put(PI_REGISTER_ID_1, P4_REGISTER_MODEL_1)
                    .build();
    private static final ImmutableMap<PiRegisterId, PiRegisterModel> REGISTERS_2 =
            new ImmutableMap.Builder<PiRegisterId, PiRegisterModel>()
                    .put(PI_REGISTER_ID_2, P4_REGISTER_MODEL_2)
                    .build();

    /* Match Fields */
    private static final PiMatchFieldId PI_MATCH_FIELD_ID_1 = PiMatchFieldId.of("MatchField1");
    private static final PiMatchFieldId PI_MATCH_FIELD_ID_2 = PiMatchFieldId.of("MatchField2");

    private static final int MATCH_FIELD_BIT_WIDTH_1 = 8;
    private static final int MATCH_FIELD_BIT_WIDTH_2 = 16;

    private static final PiMatchType PI_MATCH_TYPE_1 = PiMatchType.EXACT;
    private static final PiMatchType PI_MATCH_TYPE_2 = PiMatchType.TERNARY;

    private static final PiMatchFieldModel P4_MATCH_FIELD_MODEL_1 =
            new P4MatchFieldModel(PI_MATCH_FIELD_ID_1, MATCH_FIELD_BIT_WIDTH_1, PI_MATCH_TYPE_1);
    private static final PiMatchFieldModel P4_MATCH_FIELD_MODEL_2 =
            new P4MatchFieldModel(PI_MATCH_FIELD_ID_2, MATCH_FIELD_BIT_WIDTH_2, PI_MATCH_TYPE_2);

    private static final ImmutableMap<PiMatchFieldId, PiMatchFieldModel> MATCH_FIELDS_1 =
            new ImmutableMap.Builder<PiMatchFieldId, PiMatchFieldModel>()
                    .put(PI_MATCH_FIELD_ID_1, P4_MATCH_FIELD_MODEL_1)
                    .build();
    private static final ImmutableMap<PiMatchFieldId, PiMatchFieldModel> MATCH_FIELDS_2 =
            new ImmutableMap.Builder<PiMatchFieldId, PiMatchFieldModel>()
                    .put(PI_MATCH_FIELD_ID_2, P4_MATCH_FIELD_MODEL_2)
                    .build();

    /* Actions */
    private static final PiActionId PI_ACTION_ID_1 = PiActionId.of("Action1");
    private static final PiActionId PI_ACTION_ID_2 = PiActionId.of("Action2");

    private static final PiActionParamId PI_ACTION_PARAM_ID_1 = PiActionParamId.of("ActionParameter1");
    private static final PiActionParamId PI_ACTION_PARAM_ID_2 = PiActionParamId.of("ActionParameter2");

    private static final int ACTION_PARAM_BIT_WIDTH_1 = 8;
    private static final int ACTION_PARAM_BIT_WIDTH_2 = 16;

    private static final PiActionParamModel P4_ACTION_PARAM_MODEL_1 =
            new P4ActionParamModel(PI_ACTION_PARAM_ID_1, ACTION_PARAM_BIT_WIDTH_1);
    private static final PiActionParamModel P4_ACTION_PARAM_MODEL_2 =
            new P4ActionParamModel(PI_ACTION_PARAM_ID_2, ACTION_PARAM_BIT_WIDTH_2);

    private static final ImmutableMap<PiActionParamId, PiActionParamModel> PI_ACTION_PARAMS_1 =
            new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>()
                    .put(PI_ACTION_PARAM_ID_1, P4_ACTION_PARAM_MODEL_1)
                    .build();
    private static final ImmutableMap<PiActionParamId, PiActionParamModel> PI_ACTION_PARAMS_2 =
            new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>()
                    .put(PI_ACTION_PARAM_ID_2, P4_ACTION_PARAM_MODEL_2)
                    .build();

    private static final PiActionModel P4_ACTION_MODEL_1 = new P4ActionModel(PI_ACTION_ID_1, PI_ACTION_PARAMS_1);
    private static final PiActionModel P4_ACTION_MODEL_2 = new P4ActionModel(PI_ACTION_ID_2, PI_ACTION_PARAMS_2);

    private static final ImmutableMap<PiActionId, PiActionModel> ACTIONS_1 =
            new ImmutableMap.Builder<PiActionId, PiActionModel>()
                    .put(PI_ACTION_ID_1, P4_ACTION_MODEL_1)
                    .build();

    private static final ImmutableMap<PiActionId, PiActionModel> ACTIONS_2 =
            new ImmutableMap.Builder<PiActionId, PiActionModel>()
                    .put(PI_ACTION_ID_2, P4_ACTION_MODEL_2)
                    .build();

    /* Default Action */
    private static final PiActionId PI_ACTION_ID_DEFAULT_1 = PiActionId.of("DefaultAction1");
    private static final PiActionId PI_ACTION_ID_DEFAULT_2 = PiActionId.of("DefaultAction2");

    private static final PiActionParamId PI_ACTION_PARAM_ID_DEFAULT_1 = PiActionParamId.of("DefaultActionParameter1");
    private static final PiActionParamId PI_ACTION_PARAM_ID_DEFAULT_2 = PiActionParamId.of("DefaultActionParameter2");

    private static final int ACTION_PARAM_BIT_WIDTH_DEFAULT_1 = 8;
    private static final int ACTION_PARAM_BIT_WIDTH_DEFAULT_2 = 16;

    private static final PiActionParamModel P4_ACTION_PARAM_MODEL_DEFAULT_1 =
            new P4ActionParamModel(PI_ACTION_PARAM_ID_DEFAULT_1, ACTION_PARAM_BIT_WIDTH_DEFAULT_1);
    private static final PiActionParamModel P4_ACTION_PARAM_MODEL_DEFAULT_2 =
            new P4ActionParamModel(PI_ACTION_PARAM_ID_DEFAULT_2, ACTION_PARAM_BIT_WIDTH_DEFAULT_2);

    private static final ImmutableMap<PiActionParamId, PiActionParamModel> PI_ACTION_PARAMS_DEFAULT_1 =
            new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>()
                    .put(PI_ACTION_PARAM_ID_DEFAULT_1, P4_ACTION_PARAM_MODEL_DEFAULT_1)
                    .build();
    private static final ImmutableMap<PiActionParamId, PiActionParamModel> PI_ACTION_PARAMS_DEFAULT_2 =
            new ImmutableMap.Builder<PiActionParamId, PiActionParamModel>()
                    .put(PI_ACTION_PARAM_ID_DEFAULT_2, P4_ACTION_PARAM_MODEL_DEFAULT_2)
                    .build();

    private static final PiActionModel P4_ACTION_MODEL_DEFAULT_1 =
            new P4ActionModel(PI_ACTION_ID_DEFAULT_1, PI_ACTION_PARAMS_DEFAULT_1);
    private static final PiActionModel P4_ACTION_MODEL_DEFAULT_2 =
            new P4ActionModel(PI_ACTION_ID_DEFAULT_2, PI_ACTION_PARAMS_DEFAULT_2);

    /* Table Models */
    private static final PiTableId PI_TABLE_ID_1 = PiTableId.of("Table1");
    private static final PiTableId PI_TABLE_ID_2 = PiTableId.of("Table2");

    private static final PiTableType PI_TABLE_TYPE_1 = PiTableType.DIRECT;
    private static final PiTableType PI_TABLE_TYPE_2 = PiTableType.INDIRECT;

    private static final long MAX_SIZE_1 = 10000;
    private static final long MAX_SIZE_2 = 20000;

    private static final boolean SUPPORT_AGING_1 = true;
    private static final boolean SUPPORT_AGING_2 = false;

    private static final boolean IS_CONST_TABLE_1 = true;
    private static final boolean IS_CONST_TABLE_2 = false;

    private static final PiTableModel P4_TABLE_MODEL_1 =
            new P4TableModel(PI_TABLE_ID_1, PI_TABLE_TYPE_1, P4_ACTION_PROFILE_MODEL_1, MAX_SIZE_1, COUNTERS_1,
                             METERS_1, SUPPORT_AGING_1, MATCH_FIELDS_1, ACTIONS_1, P4_ACTION_MODEL_DEFAULT_1,
                             IS_CONST_TABLE_1);
    private static final PiTableModel P4_TABLE_MODEL_2 =
            new P4TableModel(PI_TABLE_ID_2, PI_TABLE_TYPE_2, P4_ACTION_PROFILE_MODEL_2, MAX_SIZE_2, COUNTERS_2,
                             METERS_2, SUPPORT_AGING_2, MATCH_FIELDS_2, ACTIONS_2, P4_ACTION_MODEL_DEFAULT_2,
                             IS_CONST_TABLE_2);

    /* Packet operations */
    private static final PiPacketOperationType PI_PACKET_OPERATION_TYPE_1 = PiPacketOperationType.PACKET_IN;
    private static final PiPacketOperationType PI_PACKET_OPERATION_TYPE_2 = PiPacketOperationType.PACKET_OUT;

    private static final PiControlMetadataId PI_CONTROL_METADATA_ID_1 = PiControlMetadataId.of("INGRESS PORT");
    private static final PiControlMetadataId PI_CONTROL_METADATA_ID_2 = PiControlMetadataId.of("EGRESS PORT");

    private static final int META_BIT_WIDTH_1 = 32;
    private static final int META_BIT_WIDTH_2 = 64;

    private static final PiControlMetadataModel P4_CONTROL_METADATA_MODEL_1 =
            new P4ControlMetadataModel(PI_CONTROL_METADATA_ID_1, META_BIT_WIDTH_1);
    private static final PiControlMetadataModel P4_CONTROL_METADATA_MODEL_2 =
            new P4ControlMetadataModel(PI_CONTROL_METADATA_ID_2, META_BIT_WIDTH_2);

    /* Pipeline Models */
    private static final ImmutableMap<PiTableId, PiTableModel> TABLES_1 =
            new ImmutableMap.Builder<PiTableId, PiTableModel>()
                    .put(PI_TABLE_ID_1, P4_TABLE_MODEL_1)
                    .build();
    private static final ImmutableMap<PiTableId, PiTableModel> TABLES_2 =
            new ImmutableMap.Builder<PiTableId, PiTableModel>()
                    .put(PI_TABLE_ID_2, P4_TABLE_MODEL_2)
                    .build();

    private static final ImmutableMap<PiActionProfileId, PiActionProfileModel> ACTION_PROFILES_1 =
            new ImmutableMap.Builder<PiActionProfileId, PiActionProfileModel>()
                    .put(PI_ACTION_PROFILE_ID_1, P4_ACTION_PROFILE_MODEL_1)
                    .build();
    private static final ImmutableMap<PiActionProfileId, PiActionProfileModel> ACTION_PROFILES_2 =
            new ImmutableMap.Builder<PiActionProfileId, PiActionProfileModel>()
                    .put(PI_ACTION_PROFILE_ID_2, P4_ACTION_PROFILE_MODEL_2)
                    .build();

    private static final ImmutableList<PiControlMetadataModel> METADATAS_1 =
            new ImmutableList.Builder<PiControlMetadataModel>()
                    .add(P4_CONTROL_METADATA_MODEL_1)
                    .build();
    private static final ImmutableList<PiControlMetadataModel> METADATAS_2 =
            new ImmutableList.Builder<PiControlMetadataModel>()
                    .add(P4_CONTROL_METADATA_MODEL_2)
                    .build();

    private static final PiPacketOperationModel P4_PACKET_OPERATION_MODEL_1 =
            new P4PacketOperationModel(PI_PACKET_OPERATION_TYPE_1, METADATAS_1);
    private static final PiPacketOperationModel P4_PACKET_OPERATION_MODEL_2 =
            new P4PacketOperationModel(PI_PACKET_OPERATION_TYPE_2, METADATAS_2);

    private static final ImmutableMap<PiPacketOperationType, PiPacketOperationModel> PACKET_OPERATIONS_1 =
            new ImmutableMap.Builder<PiPacketOperationType, PiPacketOperationModel>()
                    .put(PI_PACKET_OPERATION_TYPE_1, P4_PACKET_OPERATION_MODEL_1)
                    .build();
    private static final ImmutableMap<PiPacketOperationType, PiPacketOperationModel> PACKET_OPERATIONS_2 =
            new ImmutableMap.Builder<PiPacketOperationType, PiPacketOperationModel>()
                    .put(PI_PACKET_OPERATION_TYPE_2, P4_PACKET_OPERATION_MODEL_2)
                    .build();

    private static final PiPipelineModel P4_PIPELINE_MODEL_1 =
            new P4PipelineModel(TABLES_1, COUNTERS_1, METERS_1, REGISTERS_1, ACTION_PROFILES_1, PACKET_OPERATIONS_1);
    private static final PiPipelineModel SAME_AS_P4_PIPELINE_MODEL_1 =
            new P4PipelineModel(TABLES_1, COUNTERS_1, METERS_1, REGISTERS_1, ACTION_PROFILES_1, PACKET_OPERATIONS_1);
    private static final PiPipelineModel P4_PIPELINE_MODEL_2 =
            new P4PipelineModel(TABLES_2, COUNTERS_2, METERS_2, REGISTERS_1, ACTION_PROFILES_2, PACKET_OPERATIONS_2);

    /**
     * Checks that the P4PipelineModel class is immutable.
     */
    @Test
    public void testImmutability() {
        assertThatClassIsImmutable(P4PipelineModel.class);
    }

    /**
     * Checks the operation of equals(), hashCode() and toString() methods.
     */
    @Test
    public void testEquals() {
        new EqualsTester()
                .addEqualityGroup(P4_PIPELINE_MODEL_1, SAME_AS_P4_PIPELINE_MODEL_1)
                .addEqualityGroup(P4_PIPELINE_MODEL_2)
                .testEquals();
    }
}
