/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * 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.bgpio.protocol.flowspec;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.junit.Test;
import org.onosproject.bgpio.types.BgpFsActionTrafficRate;
import org.onosproject.bgpio.types.BgpFsOperatorValue;
import org.onosproject.bgpio.types.BgpFsPortNum;
import org.onosproject.bgpio.types.BgpValueType;

import com.google.common.testing.EqualsTester;

/**
 * Test for BgpFlowSpecDetails flow specification.
 */
public class BgpFlowSpecDetailsTest {

    List<BgpValueType> flowSpecComponents1 = new LinkedList<>();
    private List<BgpFsOperatorValue> operatorValue1 = new ArrayList<>();
    BgpFlowSpecDetails flowSpecDetails1 = new BgpFlowSpecDetails(flowSpecComponents1);
    BgpFsPortNum portNum1 = new BgpFsPortNum(operatorValue1);

    List<BgpValueType> flowSpecComponents = new LinkedList<>();
    private List<BgpFsOperatorValue> operatorValue = new ArrayList<>();
    BgpFlowSpecDetails flowSpecDetails = new BgpFlowSpecDetails(flowSpecComponents);
    BgpFsPortNum portNum = new BgpFsPortNum(operatorValue);

    List<BgpValueType> flowSpecComponents2 = new LinkedList<>();
    private List<BgpFsOperatorValue> operatorValue2 = new ArrayList<>();
    BgpFlowSpecDetails flowSpecDetails2 = new BgpFlowSpecDetails(flowSpecComponents2);
    BgpFsPortNum portNum2 = new BgpFsPortNum(operatorValue2);

    @Test
    public void testEquality() {
        flowSpecComponents1.add(portNum1);
        byte[] port1 = new byte[] {(byte) 0x1 };
        operatorValue1.add(new BgpFsOperatorValue((byte) 0x81, port1));
        byte[] port11 = new byte[] {(byte) 0x1 };
        operatorValue1.add(new BgpFsOperatorValue((byte) 0x82, port11));

        List<BgpValueType> fsTlvs1 = new LinkedList<>();
        fsTlvs1.add(new BgpFsActionTrafficRate((short) 1, 1));
        flowSpecDetails1.setFsActionTlv(fsTlvs1);

        flowSpecComponents.add(portNum);
        byte[] port = new byte[] {(byte) 0x1 };
        operatorValue.add(new BgpFsOperatorValue((byte) 0x81, port));
        byte[] port4 = new byte[] {(byte) 0x1 };
        operatorValue.add(new BgpFsOperatorValue((byte) 0x82, port4));

        List<BgpValueType> fsTlvs = new LinkedList<>();
        fsTlvs.add(new BgpFsActionTrafficRate((short) 1, 1));

        flowSpecComponents2.add(portNum2);
        byte[] port2 = new byte[] {(byte) 0x1 };
        operatorValue2.add(new BgpFsOperatorValue((byte) 0x82, port2));
        byte[] port22 = new byte[] {(byte) 0x1 };
        operatorValue2.add(new BgpFsOperatorValue((byte) 0x82, port22));

        List<BgpValueType> fsTlvs2 = new LinkedList<>();
        fsTlvs2.add(new BgpFsActionTrafficRate((short) 1, 1));
        flowSpecDetails2.setFsActionTlv(fsTlvs2);

        new EqualsTester()
        .addEqualityGroup(flowSpecDetails1, flowSpecDetails)
        .addEqualityGroup(flowSpecDetails2)
        .testEquals();
    }
}
