/*
 * Copyright 2015 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.codec.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.SortedMap;
import java.util.TreeMap;

import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.EthType;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.VlanId;
import org.onosproject.codec.JsonCodec;
import org.onosproject.core.CoreService;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.GridType;
import org.onosproject.net.Lambda;
import org.onosproject.net.OchSignal;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthCriterion;
import org.onosproject.net.flow.criteria.EthTypeCriterion;
import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.IPDscpCriterion;
import org.onosproject.net.flow.criteria.IPEcnCriterion;
import org.onosproject.net.flow.criteria.IPProtocolCriterion;
import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
import org.onosproject.net.flow.criteria.IndexedLambdaCriterion;
import org.onosproject.net.flow.criteria.MplsCriterion;
import org.onosproject.net.flow.criteria.OchSignalCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.SctpPortCriterion;
import org.onosproject.net.flow.criteria.TcpPortCriterion;
import org.onosproject.net.flow.criteria.UdpPortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.criteria.VlanPcpCriterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.onosproject.net.NetTestTools.APP_ID;

/**
 * Flow rule codec unit tests.
 */
public class FlowRuleCodecTest {

    MockCodecContext context;
    JsonCodec<FlowRule> flowRuleCodec;
    final CoreService mockCoreService = createMock(CoreService.class);

    /**
     * Sets up for each test.  Creates a context and fetches the flow rule
     * codec.
     */
    @Before
    public void setUp() {
        context = new MockCodecContext();
        flowRuleCodec = context.codec(FlowRule.class);
        assertThat(flowRuleCodec, notNullValue());

        expect(mockCoreService.registerApplication(FlowRuleCodec.REST_APP_ID))
                .andReturn(APP_ID).anyTimes();
        replay(mockCoreService);
        context.registerService(CoreService.class, mockCoreService);
    }

    /**
     * Reads in a rule from the given resource and decodes it.
     *
     * @param resourceName resource to use to read the JSON for the rule
     * @return decoded flow rule
     * @throws IOException if processing the resource fails
     */
    private FlowRule getRule(String resourceName) throws IOException {
        InputStream jsonStream = FlowRuleCodecTest.class
                .getResourceAsStream(resourceName);
        JsonNode json = context.mapper().readTree(jsonStream);
        assertThat(json, notNullValue());
        FlowRule rule = flowRuleCodec.decode((ObjectNode) json, context);
        assertThat(rule, notNullValue());
        return rule;
    }

    /**
     * Checks that the data shared by all the resources is correct for a
     * given rule.
     *
     * @param rule rule to check
     */
    private void checkCommonData(FlowRule rule) {
        assertThat(rule.appId(), is(APP_ID.id()));
        assertThat(rule.isPermanent(), is(false));
        assertThat(rule.timeout(), is(1));
        assertThat(rule.priority(), is(1));
        assertThat(rule.deviceId().toString(), is("of:0000000000000001"));
    }

    /**
     * Checks that a simple rule decodes properly.
     *
     * @throws IOException if the resource cannot be processed
     */
    @Test
    public void codecSimpleFlowTest() throws IOException {
        FlowRule rule = getRule("simple-flow.json");

        checkCommonData(rule);

        assertThat(rule.selector().criteria().size(), is(1));
        Criterion criterion1 = rule.selector().criteria().iterator().next();
        assertThat(criterion1.type(), is(Criterion.Type.ETH_TYPE));
        assertThat(((EthTypeCriterion) criterion1).ethType(), is(new EthType(2054)));

        assertThat(rule.treatment().allInstructions().size(), is(1));
        Instruction instruction1 = rule.treatment().allInstructions().get(0);
        assertThat(instruction1.type(), is(Instruction.Type.OUTPUT));
        assertThat(((Instructions.OutputInstruction) instruction1).port(), is(PortNumber.CONTROLLER));
    }

    SortedMap<String, Instruction> instructions = new TreeMap<>();

    /**
     * Looks up an instruction in the instruction map based on type and subtype.
     *
     * @param type type string
     * @param subType subtype string
     * @return instruction that matches
     */
    private Instruction getInstruction(Instruction.Type type, String subType) {
        Instruction instruction = instructions.get(type.name() + "/" + subType);
        assertThat(instruction, notNullValue());
        assertThat(instruction.type(), is(type));
        return instruction;
    }

    /**
     * Checks that a rule with one of each instruction type decodes properly.
     *
     * @throws IOException if the resource cannot be processed
     */
    @Test
    public void decodeInstructionsFlowTest() throws Exception {
        FlowRule rule = getRule("instructions-flow.json");

        checkCommonData(rule);

        rule.treatment().allInstructions()
                .stream()
                .forEach(instruction ->
                {
                    String subType;
                    if (instruction.type() == Instruction.Type.L0MODIFICATION) {
                        subType = ((L0ModificationInstruction) instruction)
                                .subtype().name();
                    } else if (instruction.type() == Instruction.Type.L2MODIFICATION) {
                        subType = ((L2ModificationInstruction) instruction)
                                .subtype().name();
                    } else if (instruction.type() == Instruction.Type.L3MODIFICATION) {
                        subType = ((L3ModificationInstruction) instruction)
                                .subtype().name();
                    } else {
                        subType = "";
                    }
                    instructions.put(
                            instruction.type().name() + "/" + subType, instruction);
                });

        assertThat(rule.treatment().allInstructions().size(), is(19));

        Instruction instruction;

        instruction = getInstruction(Instruction.Type.OUTPUT, "");
        assertThat(instruction.type(), is(Instruction.Type.OUTPUT));
        assertThat(((Instructions.OutputInstruction) instruction).port(), is(PortNumber.CONTROLLER));

        instruction = getInstruction(Instruction.Type.L2MODIFICATION,
                L2ModificationInstruction.L2SubType.ETH_SRC.name());
        assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
        assertThat(((L2ModificationInstruction.ModEtherInstruction) instruction).mac(),
                is(MacAddress.valueOf("12:34:56:78:90:12")));

        instruction = getInstruction(Instruction.Type.L2MODIFICATION,
                L2ModificationInstruction.L2SubType.ETH_DST.name());
        assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
        assertThat(((L2ModificationInstruction.ModEtherInstruction) instruction).mac(),
                is(MacAddress.valueOf("98:76:54:32:01:00")));

        instruction = getInstruction(Instruction.Type.L2MODIFICATION,
                L2ModificationInstruction.L2SubType.VLAN_ID.name());
        assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
        assertThat(((L2ModificationInstruction.ModVlanIdInstruction) instruction).vlanId().toShort(),
                is((short) 22));

        instruction = getInstruction(Instruction.Type.L2MODIFICATION,
                L2ModificationInstruction.L2SubType.VLAN_PCP.name());
        assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
        assertThat(((L2ModificationInstruction.ModVlanPcpInstruction) instruction).vlanPcp(),
                is((byte) 1));

        instruction = getInstruction(Instruction.Type.L2MODIFICATION,
                L2ModificationInstruction.L2SubType.MPLS_LABEL.name());
        assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
        assertThat(((L2ModificationInstruction.ModMplsLabelInstruction) instruction)
                        .label().shortValue(),
                is((short) 777));

        instruction = getInstruction(Instruction.Type.L2MODIFICATION,
                L2ModificationInstruction.L2SubType.MPLS_PUSH.name());
        assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
        assertThat(((L2ModificationInstruction.PushHeaderInstructions) instruction)
                        .ethernetType().toShort(),
                is(Ethernet.MPLS_UNICAST));

        instruction = getInstruction(Instruction.Type.L2MODIFICATION,
                L2ModificationInstruction.L2SubType.MPLS_POP.name());
        assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
        assertThat(((L2ModificationInstruction.PushHeaderInstructions) instruction)
                        .ethernetType().toShort(),
                is(Ethernet.MPLS_UNICAST));

        instruction = getInstruction(Instruction.Type.L2MODIFICATION,
                L2ModificationInstruction.L2SubType.DEC_MPLS_TTL.name());
        assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
        assertThat(instruction, instanceOf(L2ModificationInstruction.ModMplsTtlInstruction.class));

        instruction = getInstruction(Instruction.Type.L2MODIFICATION,
                L2ModificationInstruction.L2SubType.VLAN_POP.name());
        assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
        assertThat(instruction, instanceOf(L2ModificationInstruction.PopVlanInstruction.class));

        instruction = getInstruction(Instruction.Type.L2MODIFICATION,
                L2ModificationInstruction.L2SubType.VLAN_PUSH.name());
        assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION));
        assertThat(instruction, instanceOf(L2ModificationInstruction.PushHeaderInstructions.class));

        instruction = getInstruction(Instruction.Type.L3MODIFICATION,
                L3ModificationInstruction.L3SubType.IPV4_SRC.name());
        assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
        assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(),
                is(IpAddress.valueOf("1.2.3.4")));

        instruction = getInstruction(Instruction.Type.L3MODIFICATION,
                L3ModificationInstruction.L3SubType.IPV4_DST.name());
        assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
        assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(),
                is(IpAddress.valueOf("1.2.3.3")));

        instruction = getInstruction(Instruction.Type.L3MODIFICATION,
                L3ModificationInstruction.L3SubType.IPV6_SRC.name());
        assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
        assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(),
                is(IpAddress.valueOf("1.2.3.2")));

        instruction = getInstruction(Instruction.Type.L3MODIFICATION,
                L3ModificationInstruction.L3SubType.IPV6_DST.name());
        assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
        assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(),
                is(IpAddress.valueOf("1.2.3.1")));

        instruction = getInstruction(Instruction.Type.L3MODIFICATION,
                L3ModificationInstruction.L3SubType.IPV6_FLABEL.name());
        assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION));
        assertThat(((L3ModificationInstruction.ModIPv6FlowLabelInstruction) instruction)
                .flowLabel(),
                is(8));

        instruction = getInstruction(Instruction.Type.L0MODIFICATION,
                L0ModificationInstruction.L0SubType.LAMBDA.name());
        assertThat(instruction.type(), is(Instruction.Type.L0MODIFICATION));
        assertThat(((L0ModificationInstruction.ModLambdaInstruction) instruction)
                        .lambda(),
                is((short) 7));

        instruction = getInstruction(Instruction.Type.L0MODIFICATION,
                L0ModificationInstruction.L0SubType.OCH.name());
        assertThat(instruction.type(), is(Instruction.Type.L0MODIFICATION));
        L0ModificationInstruction.ModOchSignalInstruction och =
                (L0ModificationInstruction.ModOchSignalInstruction) instruction;
        assertThat(och.lambda().spacingMultiplier(), is(4));
        assertThat(och.lambda().slotGranularity(), is(8));
        assertThat(och.lambda().gridType(), is(GridType.DWDM));
        assertThat(och.lambda().channelSpacing(), is(ChannelSpacing.CHL_100GHZ));
    }

    SortedMap<String, Criterion> criteria = new TreeMap<>();

    /**
     * Looks up a criterion in the instruction map based on type and subtype.
     *
     * @param type type string
     * @return criterion that matches
     */
    private Criterion getCriterion(Criterion.Type type) {
        Criterion criterion = criteria.get(type.name());
        assertThat(criterion.type(), is(type));
        return criterion;
    }

    /**
     * Checks that a rule with one of each kind of criterion decodes properly.
     *
     * @throws IOException if the resource cannot be processed
     */
    @Test
    public void codecCriteriaFlowTest() throws Exception {
        FlowRule rule = getRule("criteria-flow.json");

        checkCommonData(rule);

        assertThat(rule.selector().criteria().size(), is(32));

        rule.selector().criteria()
                .stream()
                .forEach(criterion ->
                        criteria.put(criterion.type().name(), criterion));

        Criterion criterion;

        criterion = getCriterion(Criterion.Type.ETH_TYPE);
        assertThat(((EthTypeCriterion) criterion).ethType(), is(new EthType(2054)));

        criterion = getCriterion(Criterion.Type.ETH_DST);
        assertThat(((EthCriterion) criterion).mac(),
                is(MacAddress.valueOf("00:11:22:33:44:55")));

        criterion = getCriterion(Criterion.Type.ETH_SRC);
        assertThat(((EthCriterion) criterion).mac(),
                is(MacAddress.valueOf("00:11:22:33:44:55")));

        criterion = getCriterion(Criterion.Type.IN_PORT);
        assertThat(((PortCriterion) criterion).port(),
                is(PortNumber.portNumber(23)));

        criterion = getCriterion(Criterion.Type.IN_PHY_PORT);
        assertThat(((PortCriterion) criterion).port(),
                is(PortNumber.portNumber(44)));

        criterion = getCriterion(Criterion.Type.VLAN_VID);
        assertThat(((VlanIdCriterion) criterion).vlanId(),
                is(VlanId.vlanId((short) 777)));

        criterion = getCriterion(Criterion.Type.VLAN_PCP);
        assertThat(((VlanPcpCriterion) criterion).priority(),
                is(((byte) 3)));

        criterion = getCriterion(Criterion.Type.IP_DSCP);
        assertThat(((IPDscpCriterion) criterion).ipDscp(),
                is(((byte) 2)));

        criterion = getCriterion(Criterion.Type.IP_ECN);
        assertThat(((IPEcnCriterion) criterion).ipEcn(),
                is(((byte) 1)));

        criterion = getCriterion(Criterion.Type.IP_PROTO);
        assertThat(((IPProtocolCriterion) criterion).protocol(),
                is(((short) 4)));

        criterion = getCriterion(Criterion.Type.IPV4_SRC);
        assertThat(((IPCriterion) criterion).ip(),
                is((IpPrefix.valueOf("1.2.0.0/32"))));

        criterion = getCriterion(Criterion.Type.IPV4_DST);
        assertThat(((IPCriterion) criterion).ip(),
                is((IpPrefix.valueOf("2.2.0.0/32"))));

        criterion = getCriterion(Criterion.Type.IPV6_SRC);
        assertThat(((IPCriterion) criterion).ip(),
                is((IpPrefix.valueOf("3.2.0.0/32"))));

        criterion = getCriterion(Criterion.Type.IPV6_DST);
        assertThat(((IPCriterion) criterion).ip(),
                is((IpPrefix.valueOf("4.2.0.0/32"))));

        criterion = getCriterion(Criterion.Type.TCP_SRC);
        assertThat(((TcpPortCriterion) criterion).tcpPort(),
                is(80));

        criterion = getCriterion(Criterion.Type.TCP_DST);
        assertThat(((TcpPortCriterion) criterion).tcpPort(),
                is(443));

        criterion = getCriterion(Criterion.Type.UDP_SRC);
        assertThat(((UdpPortCriterion) criterion).udpPort(),
                is(180));

        criterion = getCriterion(Criterion.Type.UDP_DST);
        assertThat(((UdpPortCriterion) criterion).udpPort(),
                is(1443));

        criterion = getCriterion(Criterion.Type.SCTP_SRC);
        assertThat(((SctpPortCriterion) criterion).sctpPort(),
                is(280));

        criterion = getCriterion(Criterion.Type.SCTP_DST);
        assertThat(((SctpPortCriterion) criterion).sctpPort(),
                is(2443));

        criterion = getCriterion(Criterion.Type.ICMPV4_TYPE);
        assertThat(((IcmpTypeCriterion) criterion).icmpType(),
                is((short) 24));

        criterion = getCriterion(Criterion.Type.ICMPV4_CODE);
        assertThat(((IcmpCodeCriterion) criterion).icmpCode(),
                is((short) 16));

        criterion = getCriterion(Criterion.Type.ICMPV6_TYPE);
        assertThat(((Icmpv6TypeCriterion) criterion).icmpv6Type(),
                is((short) 14));

        criterion = getCriterion(Criterion.Type.ICMPV6_CODE);
        assertThat(((Icmpv6CodeCriterion) criterion).icmpv6Code(),
                is((short) 6));

        criterion = getCriterion(Criterion.Type.IPV6_FLABEL);
        assertThat(((IPv6FlowLabelCriterion) criterion).flowLabel(),
                is(8));

        criterion = getCriterion(Criterion.Type.IPV6_ND_TARGET);
        assertThat(((IPv6NDTargetAddressCriterion) criterion)
                        .targetAddress().toString(),
                is("1111:2222:3333:4444:5555:6666:7777:8888"));

        criterion = getCriterion(Criterion.Type.IPV6_ND_SLL);
        assertThat(((IPv6NDLinkLayerAddressCriterion) criterion).mac(),
                is(MacAddress.valueOf("00:11:22:33:44:56")));

        criterion = getCriterion(Criterion.Type.IPV6_ND_TLL);
        assertThat(((IPv6NDLinkLayerAddressCriterion) criterion).mac(),
                is(MacAddress.valueOf("00:11:22:33:44:57")));

        criterion = getCriterion(Criterion.Type.MPLS_LABEL);
        assertThat(((MplsCriterion) criterion).label(),
                is(MplsLabel.mplsLabel(123)));

        criterion = getCriterion(Criterion.Type.IPV6_EXTHDR);
        assertThat(((IPv6ExthdrFlagsCriterion) criterion).exthdrFlags(),
                is(99));

        criterion = getCriterion(Criterion.Type.OCH_SIGID);
        assertThat(((IndexedLambdaCriterion) criterion).lambda(),
                is(Lambda.indexedLambda(122)));
    }

    /**
     * Checks that a rule with a SigId criterion decodes properly.
     *
     * @throws IOException if the resource cannot be processed
     */
    @Test
    public void codecSigIdCriteriaFlowTest() throws Exception {
        FlowRule rule = getRule("sigid-flow.json");

        checkCommonData(rule);

        assertThat(rule.selector().criteria().size(), is(1));
        Criterion criterion = rule.selector().criteria().iterator().next();
        assertThat(criterion.type(), is(Criterion.Type.OCH_SIGID));
        Lambda lambda = ((OchSignalCriterion) criterion).lambda();
        assertThat(lambda, instanceOf(OchSignal.class));
        OchSignal ochSignal = (OchSignal) lambda;
        assertThat(ochSignal.spacingMultiplier(), is(3));
        assertThat(ochSignal.slotGranularity(), is(4));
        assertThat(ochSignal.gridType(), is(GridType.CWDM));
        assertThat(ochSignal.channelSpacing(), is(ChannelSpacing.CHL_25GHZ));
    }

}
