/*
 * 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 org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.onlab.util.HexString;
import org.onosproject.net.OduSignalId;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions.DropInstruction;
import org.onosproject.net.flow.instructions.Instructions.NoActionInstruction;
import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction;
import org.onosproject.net.flow.instructions.L1ModificationInstruction.ModOduSignalIdInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;

import com.fasterxml.jackson.databind.JsonNode;

/**
 * Hamcrest matcher for instructions.
 */
public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {

    private final Instruction instruction;

    private InstructionJsonMatcher(Instruction instructionValue) {
        instruction = instructionValue;
    }

    /**
     * Matches the contents of a push header instruction.
     *
     * @param instructionJson JSON instruction to match
     * @param description Description object used for recording errors
     * @return true if contents match, false otherwise
     */
    private boolean matchPushHeaderInstruction(JsonNode instructionJson,
                                               Description description) {
        PushHeaderInstructions instructionToMatch =
                (PushHeaderInstructions) instruction;
        final String jsonSubtype = instructionJson.get("subtype").textValue();
        if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
            description.appendText("subtype was " + jsonSubtype);
            return false;
        }

        final String jsonType = instructionJson.get("type").textValue();
        if (!instructionToMatch.type().name().equals(jsonType)) {
            description.appendText("type was " + jsonType);
            return false;
        }

        final JsonNode ethJson = instructionJson.get("ethernetType");
        if (ethJson == null) {
            description.appendText("ethernetType was not null");
            return false;
        }

        if (instructionToMatch.ethernetType().toShort() != ethJson.asInt()) {
            description.appendText("ethernetType was " + ethJson);
            return false;
        }

        return true;
    }

    /**
     * Matches the contents of an output instruction.
     *
     * @param instructionJson JSON instruction to match
     * @param description Description object used for recording errors
     * @return true if contents match, false otherwise
     */
    private boolean matchOutputInstruction(JsonNode instructionJson,
                                           Description description) {
        final String jsonType = instructionJson.get("type").textValue();
        OutputInstruction instructionToMatch = (OutputInstruction) instruction;
        if (!instructionToMatch.type().name().equals(jsonType)) {
            description.appendText("type was " + jsonType);
            return false;
        }

        if (instructionJson.get("port").isLong() ||
                instructionJson.get("port").isInt()) {
            final long jsonPort = instructionJson.get("port").asLong();
            if (instructionToMatch.port().toLong() != (jsonPort)) {
                description.appendText("port was " + jsonPort);
                return false;
            }
        } else if (instructionJson.get("port").isTextual()) {
            final String jsonPort = instructionJson.get("port").textValue();
            if (!instructionToMatch.port().toString().equals(jsonPort)) {
                description.appendText("port was " + jsonPort);
                return false;
            }
        } else {
            final String jsonPort = instructionJson.get("port").toString();
            description.appendText("Unmathcing types ");
            description.appendText("instructionToMatch " + instructionToMatch.port().toString());
            description.appendText("jsonPort " + jsonPort);
        }

        return true;
    }

    /**
     * Matches the contents of a mod lambda instruction.
     *
     * @param instructionJson JSON instruction to match
     * @param description Description object used for recording errors
     * @return true if contents match, false otherwise
     */
    private boolean matchModLambdaInstruction(JsonNode instructionJson,
                                              Description description) {
        ModLambdaInstruction instructionToMatch =
                (ModLambdaInstruction) instruction;
        final String jsonSubtype = instructionJson.get("subtype").textValue();
        if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
            description.appendText("subtype was " + jsonSubtype);
            return false;
        }

        final String jsonType = instructionJson.get("type").textValue();
        if (!instructionToMatch.type().name().equals(jsonType)) {
            description.appendText("type was " + jsonType);
            return false;
        }

        final long jsonLambda = instructionJson.get("lambda").shortValue();
        if (instructionToMatch.lambda() != jsonLambda) {
            description.appendText("lambda was " + jsonLambda);
            return false;
        }

        return true;
    }

    /**
     * Matches the contents of a mod OCh singal instruction.
     *
     * @param instructionJson JSON instruction to match
     * @param description Description object used for recording errors
     * @return true if contents matches, false otherwise
     */
    private boolean matchModOchSingalInstruction(JsonNode instructionJson,
                                                 Description description) {
        ModOchSignalInstruction instructionToMatch =
                (ModOchSignalInstruction) instruction;

        String jsonSubType = instructionJson.get("subtype").textValue();
        if (!instructionToMatch.subtype().name().equals(jsonSubType)) {
            description.appendText("subtype was " + jsonSubType);
            return false;
        }

        String jsonType = instructionJson.get("type").textValue();
        if (!instructionToMatch.type().name().equals(jsonType)) {
            description.appendText("type was " + jsonType);
            return false;
        }

        String jsonGridType = instructionJson.get("gridType").textValue();
        if (!instructionToMatch.lambda().gridType().name().equals(jsonGridType)) {
            description.appendText("gridType was " + jsonGridType);
            return false;
        }

        String jsonChannelSpacing = instructionJson.get("channelSpacing").textValue();
        if (!instructionToMatch.lambda().channelSpacing().name().equals(jsonChannelSpacing)) {
            description.appendText("channelSpacing was " + jsonChannelSpacing);
            return false;
        }

        int jsonSpacingMultiplier = instructionJson.get("spacingMultiplier").intValue();
        if (instructionToMatch.lambda().spacingMultiplier() != jsonSpacingMultiplier) {
            description.appendText("spacingMultiplier was " + jsonSpacingMultiplier);
            return false;
        }

        int jsonSlotGranularity = instructionJson.get("slotGranularity").intValue();
        if (instructionToMatch.lambda().slotGranularity() != jsonSlotGranularity) {
            description.appendText("slotGranularity was " + jsonSlotGranularity);
            return false;
        }

        return true;
    }

    /**
     * Matches the contents of a mod ODU singal Id instruction.
     *
     * @param instructionJson JSON instruction to match
     * @param description Description object used for recording errors
     * @return true if contents matches, false otherwise
     */
    private boolean matchModOduSingalIdInstruction(JsonNode instructionJson,
                                                   Description description) {
        ModOduSignalIdInstruction instructionToMatch =
                (ModOduSignalIdInstruction) instruction;
        String jsonSubType = instructionJson.get("subtype").textValue();
        if (!instructionToMatch.subtype().name().equals(jsonSubType)) {
            description.appendText("subtype was " + jsonSubType);
            return false;
        }
        String jsonType = instructionJson.get("type").textValue();
        if (!instructionToMatch.type().name().equals(jsonType)) {
            description.appendText("type was " + jsonType);
            return false;
        }
        final JsonNode jsonOduSignal = instructionJson.get("oduSignalId");
        int jsonTpn = jsonOduSignal.get("tributaryPortNumber").intValue();
        int jsonTsLen = jsonOduSignal.get("tributarySlotLength").intValue();
        byte [] tributaryBitMap = HexString.fromHexString(jsonOduSignal.get("tributarySlotBitmap").asText());
        OduSignalId  jsonOduSignalId = OduSignalId.oduSignalId(jsonTpn, jsonTsLen, tributaryBitMap);
        if (!instructionToMatch.oduSignalId().equals(jsonOduSignalId)) {
            description.appendText("oduSignalId was " + instructionToMatch);
            return false;
        }
        return true;
    }


    /**
     * Matches the contents of a mod Ethernet instruction.
     *
     * @param instructionJson JSON instruction to match
     * @param description Description object used for recording errors
     * @return true if contents match, false otherwise
     */
    private boolean matchModEtherInstruction(JsonNode instructionJson,
                                             Description description) {
        ModEtherInstruction instructionToMatch =
                (ModEtherInstruction) instruction;
        final String jsonSubtype = instructionJson.get("subtype").textValue();
        if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
            description.appendText("subtype was " + jsonSubtype);
            return false;
        }

        final String jsonType = instructionJson.get("type").textValue();
        if (!instructionToMatch.type().name().equals(jsonType)) {
            description.appendText("type was " + jsonType);
            return false;
        }

        final String jsonMac = instructionJson.get("mac").textValue();
        final String mac = instructionToMatch.mac().toString();
        if (!mac.equals(jsonMac)) {
            description.appendText("mac was " + jsonMac);
            return false;
        }

        return true;
    }

    /**
     * Matches the contents of a mod vlan id instruction.
     *
     * @param instructionJson JSON instruction to match
     * @param description Description object used for recording errors
     * @return true if contents match, false otherwise
     */
    private boolean matchModVlanIdInstruction(JsonNode instructionJson,
                                           Description description) {
        ModVlanIdInstruction instructionToMatch =
                (ModVlanIdInstruction) instruction;
        final String jsonSubtype = instructionJson.get("subtype").textValue();
        if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
            description.appendText("subtype was " + jsonSubtype);
            return false;
        }

        final String jsonType = instructionJson.get("type").textValue();
        if (!instructionToMatch.type().name().equals(jsonType)) {
            description.appendText("type was " + jsonType);
            return false;
        }

        final short jsonVlanId = instructionJson.get("vlanId").shortValue();
        final short vlanId = instructionToMatch.vlanId().toShort();
        if (jsonVlanId != vlanId) {
            description.appendText("vlan id was " + jsonVlanId);
            return false;
        }

        return true;
    }

    /**
     * Matches the contents of a mod vlan pcp instruction.
     *
     * @param instructionJson JSON instruction to match
     * @param description Description object used for recording errors
     * @return true if contents match, false otherwise
     */
    private boolean matchModVlanPcpInstruction(JsonNode instructionJson,
                                              Description description) {
        ModVlanPcpInstruction instructionToMatch =
                (ModVlanPcpInstruction) instruction;
        final String jsonSubtype = instructionJson.get("subtype").textValue();
        if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
            description.appendText("subtype was " + jsonSubtype);
            return false;
        }

        final String jsonType = instructionJson.get("type").textValue();
        if (!instructionToMatch.type().name().equals(jsonType)) {
            description.appendText("type was " + jsonType);
            return false;
        }

        final short jsonVlanPcp = instructionJson.get("vlanPcp").shortValue();
        final short vlanId = instructionToMatch.vlanPcp();
        if (jsonVlanPcp != vlanId) {
            description.appendText("vlan pcp was " + jsonVlanPcp);
            return false;
        }

        return true;
    }

    /**
     * Matches the contents of a mod ip instruction.
     *
     * @param instructionJson JSON instruction to match
     * @param description Description object used for recording errors
     * @return true if contents match, false otherwise
     */
    private boolean matchModIpInstruction(JsonNode instructionJson,
                                          Description description) {
        ModIPInstruction instructionToMatch =
                (ModIPInstruction) instruction;
        final String jsonSubtype = instructionJson.get("subtype").textValue();
        if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
            description.appendText("subtype was " + jsonSubtype);
            return false;
        }

        final String jsonType = instructionJson.get("type").textValue();
        if (!instructionToMatch.type().name().equals(jsonType)) {
            description.appendText("type was " + jsonType);
            return false;
        }

        final String jsonIp = instructionJson.get("ip").textValue();
        final String ip = instructionToMatch.ip().toString();
        if (!ip.equals(jsonIp)) {
            description.appendText("ip was " + jsonIp);
            return false;
        }

        return true;
    }

    /**
     * Matches the contents of a mod IPv6 Flow Label instruction.
     *
     * @param instructionJson JSON instruction to match
     * @param description Description object used for recording errors
     * @return true if contents match, false otherwise
     */
    private boolean matchModIPv6FlowLabelInstruction(JsonNode instructionJson,
                                                     Description description) {
        ModIPv6FlowLabelInstruction instructionToMatch =
                (ModIPv6FlowLabelInstruction) instruction;
        final String jsonSubtype = instructionJson.get("subtype").textValue();
        if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
            description.appendText("subtype was " + jsonSubtype);
            return false;
        }

        final String jsonType = instructionJson.get("type").textValue();
        if (!instructionToMatch.type().name().equals(jsonType)) {
            description.appendText("type was " + jsonType);
            return false;
        }

        final int jsonFlowLabel = instructionJson.get("flowLabel").intValue();
        final int flowLabel = instructionToMatch.flowLabel();
        if (flowLabel != jsonFlowLabel) {
            description.appendText("IPv6 flow label was " + jsonFlowLabel);
            return false;
        }

        return true;
    }

    /**
     * Matches the contents of a mod MPLS label instruction.
     *
     * @param instructionJson JSON instruction to match
     * @param description Description object used for recording errors
     * @return true if contents match, false otherwise
     */
    private boolean matchModMplsLabelInstruction(JsonNode instructionJson,
                                          Description description) {
        ModMplsLabelInstruction instructionToMatch =
                (ModMplsLabelInstruction) instruction;
        final String jsonSubtype = instructionJson.get("subtype").textValue();
        if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
            description.appendText("subtype was " + jsonSubtype);
            return false;
        }

        final String jsonType = instructionJson.get("type").textValue();
        if (!instructionToMatch.type().name().equals(jsonType)) {
            description.appendText("type was " + jsonType);
            return false;
        }

        final int jsonLabel = instructionJson.get("label").intValue();
        final int label = instructionToMatch.mplsLabel().toInt();
        if (label != jsonLabel) {
            description.appendText("MPLS label was " + jsonLabel);
            return false;
        }

        return true;
    }

    @Override
    public boolean matchesSafely(JsonNode jsonInstruction, Description description) {

        // check type
        final JsonNode jsonTypeNode = jsonInstruction.get("type");
        final String jsonType = jsonTypeNode.textValue();
        final String type = instruction.type().name();
        if (!jsonType.equals(type)) {
                description.appendText("type was " + type);
                return false;
        }

        if (instruction instanceof PushHeaderInstructions) {
            return matchPushHeaderInstruction(jsonInstruction, description);
        } else if (instruction instanceof DropInstruction) {
            return true;
        } else if (instruction instanceof OutputInstruction) {
            return matchOutputInstruction(jsonInstruction, description);
        } else if (instruction instanceof ModLambdaInstruction) {
            return matchModLambdaInstruction(jsonInstruction, description);
        } else if (instruction instanceof ModOchSignalInstruction) {
            return matchModOchSingalInstruction(jsonInstruction, description);
        } else if (instruction instanceof ModEtherInstruction) {
            return matchModEtherInstruction(jsonInstruction, description);
        } else if (instruction instanceof ModVlanIdInstruction) {
            return matchModVlanIdInstruction(jsonInstruction, description);
        } else if (instruction instanceof ModVlanPcpInstruction) {
            return matchModVlanPcpInstruction(jsonInstruction, description);
        } else if (instruction instanceof ModIPInstruction) {
            return matchModIpInstruction(jsonInstruction, description);
        } else if (instruction instanceof ModIPv6FlowLabelInstruction) {
            return matchModIPv6FlowLabelInstruction(jsonInstruction,
                                                    description);
        } else if (instruction instanceof ModMplsLabelInstruction) {
            return matchModMplsLabelInstruction(jsonInstruction, description);
        } else if (instruction instanceof ModOduSignalIdInstruction) {
            return matchModOduSingalIdInstruction(jsonInstruction, description);
        } else if (instruction instanceof NoActionInstruction) {
            return true;
        }

        return false;
    }

    @Override
    public void describeTo(Description description) {
        description.appendText(instruction.toString());
    }

    /**
     * Factory to allocate an instruction matcher.
     *
     * @param instruction instruction object we are looking for
     * @return matcher
     */
    public static InstructionJsonMatcher matchesInstruction(Instruction instruction) {
        return new InstructionJsonMatcher(instruction);
    }
}
