/*
 * Copyright 2016-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.segmentrouting.config;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.VlanId;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.config.Config;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.intf.InterfaceService;
import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
import org.onosproject.segmentrouting.pwaas.L2Mode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * App configuration object for Pwaas.
 */
public class PwaasConfig extends Config<ApplicationId> {

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    public DeviceService deviceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    public InterfaceService intfService;

    private static Logger log = LoggerFactory
            .getLogger(PwaasConfig.class);

    private static final String SRC_CP = "cP1";
    private static final String DST_CP = "cP2";
    private static final String SRC_OUTER_TAG = "cP1OuterTag";
    private static final String DST_OUTER_TAG = "cP2OuterTag";
    private static final String SRC_INNER_TAG = "cP1InnerTag";
    private static final String DST_INNER_TAG = "cP2InnerTag";
    private static final String MODE = "mode";
    private static final String SD_TAG = "sdTag";
    private static final String PW_LABEL = "pwLabel";

    public PwaasConfig(DeviceService devS, InterfaceService intfS) {

        super();

        deviceService = devS;
        intfService = intfS;
    }

    public PwaasConfig() {

        super();

        deviceService = AbstractShellCommand.get(DeviceService.class);
        intfService = AbstractShellCommand.get(InterfaceService.class);
    }
    /**
     * Error message for missing parameters.
     */
    private static final String MISSING_PARAMS = "Missing parameters in pseudo wire description";

    /**
     * Error message for invalid l2 mode.
     */
    private static final String INVALID_L2_MODE = "Invalid pseudo wire mode";

    /**
     * Error message for invalid VLAN.
     */
    private static final String INVALID_VLAN = "Vlan should be either int or */-";

    /**
     * Error message for invalid PW label.
     */
    private static final String INVALID_PW_LABEL = "Pseudowire label should be an integer";

    /**
     * Verify if the pwaas configuration block is valid.
     *
     * Here we try to ensure that the provided pseudowires will get instantiated
     * correctly in the network. We also check for any collisions with already used
     * interfaces and also between different pseudowires. Most of the restrictions stem
     * from the fact that all vlan matching is done in table 10 of ofdpa.
     *
     * @return true, if the configuration block is valid.
     *         False otherwise.
     */
    @Override
    public boolean isValid() {

        Set<DefaultL2TunnelDescription> pseudowires;
        try {
            pseudowires = getPwIds().stream()
                    .map(this::getPwDescription)
                    .collect(Collectors.toSet());

            // check semantics now and return
            return configurationValidity(pseudowires);

        } catch (IllegalArgumentException e) {
            log.warn("{}", e.getMessage());
            return false;
        }
    }

    /**
     * Helper method to verify if the tunnel is whether or not
     * supported.
     *
     * @param l2Tunnel the tunnel to verify
     * @return the result of the verification
     */
    private void verifyTunnel(DefaultL2Tunnel l2Tunnel) {

        // Service delimiting tag not supported yet.
        if (!l2Tunnel.sdTag().equals(VlanId.NONE)) {
            throw new IllegalArgumentException(String.format("Service delimiting tag not supported yet for " +
                                                             "pseudowire %d.", l2Tunnel.tunnelId()));
        }

        // Tag mode not supported yet.
        if (l2Tunnel.pwMode() == L2Mode.TAGGED) {
            throw new IllegalArgumentException(String.format("Tagged mode not supported yet for pseudowire %d.",
                                                                            l2Tunnel.tunnelId()));
        }

        // Raw mode without service delimiting tag
        // is the only mode supported for now.
    }

    /**
     * Helper method to verify if the policy is whether or not
     * supported and if policy will be successfully instantiated in the
     * network.
     *
     * @param ingressInner the ingress inner tag
     * @param ingressOuter the ingress outer tag
     * @param egressInner the egress inner tag
     * @param egressOuter the egress outer tag
     * @return the result of verification
     */
    private void verifyPolicy(ConnectPoint cP1,
                              ConnectPoint cP2,
                              VlanId ingressInner,
                              VlanId ingressOuter,
                              VlanId egressInner,
                              VlanId egressOuter,
                              Long tunnelId) {

        if (cP1.deviceId().equals(cP2.deviceId())) {
            throw new IllegalArgumentException(String.format("Pseudowire connection points can not reside in the " +
                                                             "same node, in pseudowire %d.", tunnelId));
        }

        // We can have multiple tags, all of them can be NONE,
        // indicating untagged traffic, however, the outer tag can
        // not have value if the inner tag is None
        if (ingressInner.equals(VlanId.NONE) && !ingressOuter.equals(VlanId.NONE)) {
            throw new IllegalArgumentException(String.format("Inner tag should not be empty when " +
                                                             "outer tag is set for pseudowire %d for cP1.",
                                                              tunnelId));
        }

        if (egressInner.equals(VlanId.NONE) && !egressOuter.equals(VlanId.NONE)) {
            throw new IllegalArgumentException(String.valueOf(String.format("Inner tag should not be empty when" +
                                                                            " outer tag is set for pseudowire %d " +
                                                                            "for cP2.", tunnelId)));
        }

        if (ingressInner.equals(VlanId.ANY) ||
                ingressOuter.equals(VlanId.ANY) ||
                egressInner.equals(VlanId.ANY) ||
                egressOuter.equals(VlanId.ANY)) {
            throw new IllegalArgumentException(String.valueOf(String.format("Wildcard VLAN matching not yet " +
                                                                            "supported for pseudowire %d.",
                                                                            tunnelId)));
        }

        if (((!ingressOuter.equals(VlanId.NONE) && !ingressInner.equals(VlanId.NONE)) &&
                (egressOuter.equals(VlanId.NONE) && egressInner.equals(VlanId.NONE)))
                || ((ingressOuter.equals(VlanId.NONE) && ingressInner.equals(VlanId.NONE)) &&
                (!egressOuter.equals(VlanId.NONE) && !egressInner.equals(VlanId.NONE)))) {
            throw new IllegalArgumentException(String.valueOf(String.format("Support for double tag <-> untag is not" +
                                                                                    "supported for pseudowire %d.",
                                                                            tunnelId)));
        }
        if ((!ingressInner.equals(VlanId.NONE) &&
                ingressOuter.equals(VlanId.NONE) &&
                !egressOuter.equals(VlanId.NONE))
           || (!ingressOuter.equals(VlanId.NONE) &&
                egressOuter.equals(VlanId.NONE) &&
                !ingressOuter.equals(VlanId.NONE))) {
                throw new IllegalArgumentException(String.valueOf(String.format("Support for double-tag<->" +
                                                                                "single-tag is not supported" +
                                                                                " for pseudowire %d.", tunnelId)));
        }

        if ((ingressInner.equals(VlanId.NONE) && !egressInner.equals(VlanId.NONE))
                || (!ingressInner.equals(VlanId.NONE) && egressInner.equals(VlanId.NONE))) {
            throw new IllegalArgumentException(String.valueOf(String.format("single-tag <-> untag is not supported" +
                                                                            " for pseudowire %d.", tunnelId)));
        }


        if (!ingressInner.equals(egressInner) && !ingressOuter.equals(egressOuter)) {
            throw new IllegalArgumentException(String.valueOf(String.format("We do not support changing both tags " +
                                                                             "in double tagged pws, only the outer," +
                                                                             " for pseudowire %d.", tunnelId)));
        }

        // check if cp1 and port of cp1 exist
        if (deviceService.getDevice(cP1.deviceId()) == null) {
            throw new IllegalArgumentException(String.valueOf(String.format("cP1 device %s does not exist for" +
                                                                            " pseudowire %d.", cP1.deviceId(),
                                                                            tunnelId)));
        }

        if (deviceService.getPort(cP1) == null) {
            throw new IllegalArgumentException(String.valueOf(String.format("Port %s for cP1 device %s does not" +
                                                                            " exist for pseudowire %d.", cP1.port(),
                                                                            cP1.deviceId(), tunnelId)));
        }

        // check if cp2 and port of cp2 exist
        if (deviceService.getDevice(cP2.deviceId()) == null) {
            throw new IllegalArgumentException(String.valueOf(String.format("cP2 device %s does not exist for" +
                                                                            " pseudowire %d.", cP2.deviceId(),
                                                                            tunnelId)));
        }

        if (deviceService.getPort(cP2) == null) {
            throw new IllegalArgumentException(String.valueOf(String.format("Port %s for cP2 device %s does " +
                                                                            "not exist for pseudowire %d.",
                                                                            cP2.port(), cP2.deviceId(), tunnelId)));
        }
    }

    /**
     * Verifies that the pseudowires will not conflict with each other.
     *
     * Further, check if vlans for connect points are already used.
     *
     * @param tunnel Tunnel for pw
     * @param policy Policy for pw
     * @param labelSet Label set used so far with this configuration
     * @param vlanSet Vlan set used with this configuration
     * @param tunnelSet Tunnel set used with this configuration
     */
    private void verifyGlobalValidity(DefaultL2Tunnel tunnel,
                                      DefaultL2TunnelPolicy policy,
                                      Set<MplsLabel> labelSet,
                                      Map<ConnectPoint, Set<VlanId>> vlanSet,
                                      Set<Long> tunnelSet) {

        if (tunnelSet.contains(tunnel.tunnelId())) {
            throw new IllegalArgumentException(String.valueOf(String.format("Tunnel Id %d already used by" +
                                                                           " another pseudowire, in " +
                                                                           "pseudowire %d!", tunnel.tunnelId(),
                                                                            tunnel.tunnelId())));
        }
        tunnelSet.add(tunnel.tunnelId());

        // check if tunnel id is used again
        ConnectPoint cP1 = policy.cP1();
        ConnectPoint cP2 = policy.cP2();

        // insert cps to hashmap if this is the first time seen
        if (!vlanSet.containsKey(cP1)) {
            vlanSet.put(cP1, new HashSet<VlanId>());
        }
        if (!vlanSet.containsKey(cP2)) {
            vlanSet.put(cP2, new HashSet<VlanId>());
        }

        // if single tagged or untagged vlan is the inner
        // if double tagged vlan is the outer
        VlanId vlanToCheckCP1;
        if (policy.cP1OuterTag().equals(VlanId.NONE)) {
            vlanToCheckCP1 = policy.cP1InnerTag();
        } else {
            vlanToCheckCP1 = policy.cP1OuterTag();
        }

        VlanId vlanToCheckCP2;
        if (policy.cP2OuterTag().equals(VlanId.NONE)) {
            vlanToCheckCP2 = policy.cP2InnerTag();
        } else {
            vlanToCheckCP2 = policy.cP2OuterTag();
        }

        if (labelSet.contains(tunnel.pwLabel())) {
            throw new IllegalArgumentException(String.valueOf(String.format("Label %s already used by another" +
                                                                            " pseudowire, in pseudowire %d!",
                                                                            tunnel.pwLabel(), tunnel.tunnelId())));
        }
        labelSet.add(tunnel.pwLabel());

        if (vlanSet.get(cP1).contains(vlanToCheckCP1)) {
            throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP1 %s already used " +
                                                                            "by another pseudowire, in pseudowire" +
                                                                            " %d!", vlanToCheckCP1,  cP1,
                                                                            tunnel.tunnelId())));
        }
        vlanSet.get(cP1).add(vlanToCheckCP1);

        if (vlanSet.get(cP2).contains(vlanToCheckCP2)) {
            throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP2 %s already used" +
                                                                            " by another pseudowire, in" +
                                                                            " pseudowire %d!", vlanToCheckCP2, cP2,
                                                                            tunnel.tunnelId())));
        }
        vlanSet.get(cP2).add(vlanToCheckCP2);

        // check that vlans for the connect points are not used
        intfService.getInterfacesByPort(cP1).stream()
                .forEach(intf -> {

                    // check if tagged pw affects tagged interface
                    if (intf.vlanTagged().contains(vlanToCheckCP1)) {
                        throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP1 %s already" +
                                                                                        " used for this interface, in" +
                                                                                        " pseudowire %d!",
                                                                                        vlanToCheckCP1, cP1,
                                                                                        tunnel.tunnelId())));
                    }

                    // if vlanNative != null this interface is configured with untagged traffic also
                    // check if it collides with untagged interface
                    if ((intf.vlanNative() != null) && vlanToCheckCP1.equals(VlanId.NONE)) {
                        throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for cP1 " +
                                                                                         "%s already used for this " +
                                                                                         "interface, in pseudowire " +
                                                                                         "%d!", cP1,
                                                                                         tunnel.tunnelId())));
                    }

                    // if vlanUntagged != null this interface is configured only with untagged traffic
                    // check if it collides with untagged interface
                    if ((intf.vlanUntagged() != null) && vlanToCheckCP1.equals(VlanId.NONE)) {
                        throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for " +
                                                                                         "cP1 %s already" +
                                                                                         " used for this interface," +
                                                                                         " in pseudowire %d!",
                                                                                         cP1, tunnel.tunnelId())));
                    }
                });

        intfService.getInterfacesByPort(cP2).stream()
                .forEach(intf -> {
                    if (intf.vlanTagged().contains(vlanToCheckCP2)) {
                        throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP2 %s already" +
                                                                                        " used for  this interface, " +
                                                                                        "in pseudowire %d!",
                                                                                        vlanToCheckCP2, cP2,
                                                                                        tunnel.tunnelId())));
                    }

                    // if vlanNative != null this interface is configured with untagged traffic also
                    // check if it collides with untagged interface
                    if ((intf.vlanNative() != null) && vlanToCheckCP2.equals(VlanId.NONE)) {
                        throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for cP2 %s " +
                                                                                        "already used for this" +
                                                                                        " interface, " +
                                                                                        "in pseudowire %d!",
                                                                                        cP2, tunnel.tunnelId())));
                    }

                    // if vlanUntagged != null this interface is configured only with untagged traffic
                    // check if it collides with untagged interface
                    if ((intf.vlanUntagged() != null) && vlanToCheckCP2.equals(VlanId.NONE)) {
                        throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for cP2 %s" +
                                                                                        " already" +
                                                                                        " used for this interface, " +
                                                                                        "in pseudowire %d!",
                                                                                        cP2, tunnel.tunnelId())));
                    }
                });

    }

    /**
     * Helper method to verify the integrity of the pseudo wire.
     *
     * @param l2TunnelDescription the pseudo wire description
     * @return the result of the check
     */
    private void verifyPseudoWire(DefaultL2TunnelDescription l2TunnelDescription,
                                  Set<MplsLabel> labelSet,
                                  Map<ConnectPoint, Set<VlanId>> vlanset,
                                  Set<Long> tunnelSet) {

        DefaultL2Tunnel l2Tunnel = l2TunnelDescription.l2Tunnel();
        DefaultL2TunnelPolicy l2TunnelPolicy = l2TunnelDescription.l2TunnelPolicy();

        verifyTunnel(l2Tunnel);

        verifyPolicy(
                l2TunnelPolicy.cP1(),
                l2TunnelPolicy.cP2(),
                l2TunnelPolicy.cP1InnerTag(),
                l2TunnelPolicy.cP1OuterTag(),
                l2TunnelPolicy.cP2InnerTag(),
                l2TunnelPolicy.cP2OuterTag(),
                l2Tunnel.tunnelId()
        );

        verifyGlobalValidity(l2Tunnel,
                             l2TunnelPolicy,
                             labelSet,
                             vlanset,
                             tunnelSet);

    }

    /**
     * Checks if the configured pseudowires will create problems in the network.
     * If yes, then no pseudowires is deployed from this configuration.
     *
     * @param pseudowires Set of pseudowries to validate
     * @return returns true if everything goes well.
     */
    public boolean configurationValidity(Set<DefaultL2TunnelDescription> pseudowires) {

        // structures to keep pw information
        // in order to see if instantiating them will create
        // problems
        Set<Long> tunIds = new HashSet<>();
        Set<MplsLabel> labelsUsed = new HashSet<>();
        Map<ConnectPoint, Set<VlanId>> vlanIds = new HashMap<>();

        // check that pseudowires can be instantiated in the network
        // we try to guarantee that all the pws will work before
        // instantiating any of them
        for (DefaultL2TunnelDescription pw : pseudowires) {
            verifyPseudoWire(pw, labelsUsed, vlanIds, tunIds);
        }

        return true;
    }

    /**
     * Returns all pseudo wire keys.
     *
     * @return all keys (tunnels id)
     * @throws IllegalArgumentException if wrong format
     */
    public Set<Long> getPwIds() {
        ImmutableSet.Builder<Long> builder = ImmutableSet.builder();
        object.fields().forEachRemaining(entry -> {
            Long tunnelId = Long.parseLong(entry.getKey());
            builder.add(tunnelId);
        });
        return builder.build();
    }

    /**
     * Parses a vlan as a string. Returns the VlanId if
     * provided String can be parsed as an integer or is '' / '*'
     *
     * @param vlan string as read from configuration
     * @return VlanId
     * @throws IllegalArgumentException if wrong format of vlan
     */
    public VlanId parseVlan(String vlan) {

        if (vlan.equals("*") || vlan.equals("Any")) {
            return VlanId.vlanId("Any");
        } else if (vlan.equals("") || vlan.equals("None")) {
            return VlanId.vlanId("None");
        } else {
            try {
                VlanId newVlan = VlanId.vlanId(vlan);
                return newVlan;
            } catch (IllegalArgumentException e) {
                throw new IllegalArgumentException(INVALID_VLAN);
            }
        }
    }

    /**
     *
     * @param mode RAW or TAGGED
     * @return the L2Mode if input is correct
     * @throws  IllegalArgumentException if not supported mode
     */
    public L2Mode parseMode(String mode) {

        if (!mode.equals("RAW") && !mode.equals("TAGGED")) {
            throw  new IllegalArgumentException(INVALID_L2_MODE);
        }

        return L2Mode.valueOf(mode);
    }

    /**
     *
     * @param label the mpls label of the pseudowire
     * @return the MplsLabel
     * @throws IllegalArgumentException if label is invalid
     */
    public MplsLabel parsePWLabel(String label) {

        try {
            MplsLabel pwLabel = MplsLabel.mplsLabel(label);
            return pwLabel;
        } catch (Exception e) {
            throw new IllegalArgumentException(INVALID_PW_LABEL);
        }
    }

    /**
     * Returns pw description of given pseudo wire id.
     *
     * @param tunnelId pseudo wire key
     * @return set of l2 tunnel descriptions
     * @throws IllegalArgumentException if wrong format
     */
    public DefaultL2TunnelDescription getPwDescription(Long tunnelId) {
        JsonNode pwDescription = object.get(tunnelId.toString());
        if (!hasFields((ObjectNode) pwDescription,
                      SRC_CP, SRC_INNER_TAG, SRC_OUTER_TAG,
                      DST_CP, DST_INNER_TAG, DST_OUTER_TAG,
                      MODE, SD_TAG, PW_LABEL)) {
            throw new IllegalArgumentException(MISSING_PARAMS);
        }
        String tempString;

        tempString = pwDescription.get(SRC_CP).asText();
        ConnectPoint srcCp = ConnectPoint.deviceConnectPoint(tempString);

        tempString = pwDescription.get(DST_CP).asText();
        ConnectPoint dstCp = ConnectPoint.deviceConnectPoint(tempString);

        tempString = pwDescription.get(SRC_INNER_TAG).asText();
        VlanId srcInnerTag = parseVlan(tempString);

        tempString = pwDescription.get(SRC_OUTER_TAG).asText();
        VlanId srcOuterTag = parseVlan(tempString);

        tempString = pwDescription.get(DST_INNER_TAG).asText();
        VlanId dstInnerTag = parseVlan(tempString);

        tempString = pwDescription.get(DST_OUTER_TAG).asText();
        VlanId dstOuterTag = parseVlan(tempString);

        tempString = pwDescription.get(MODE).asText();
        L2Mode l2Mode = parseMode(tempString);

        tempString = pwDescription.get(SD_TAG).asText();
        VlanId sdTag = parseVlan(tempString);

        tempString = pwDescription.get(PW_LABEL).asText();
        MplsLabel pwLabel = parsePWLabel(tempString);

        DefaultL2Tunnel l2Tunnel = new DefaultL2Tunnel(
                l2Mode,
                sdTag,
                tunnelId,
                pwLabel
        );

        DefaultL2TunnelPolicy l2TunnelPolicy = new DefaultL2TunnelPolicy(
                tunnelId,
                srcCp,
                srcInnerTag,
                srcOuterTag,
                dstCp,
                dstInnerTag,
                dstOuterTag
        );

        return new DefaultL2TunnelDescription(l2Tunnel, l2TunnelPolicy);
    }

    /**
     * Removes a pseudowire from the configuration tree.
     * @param pwId Pseudowire id
     * @return null if pwId did not exist, or the object representing the
     * udpated configuration tree
     */
    public ObjectNode removePseudowire(String pwId) {

        JsonNode value = object.remove(pwId);
        if (value == null) {
            return (ObjectNode) value;
        } else {
            return object;
        }
    }

    /**
     * Adds a pseudowire to the configuration tree of pwwas. It also checks
     * if the configuration is valid, if not return null and does not add the node,
     * if yes return the new configuration. Caller will propagate update events.
     *
     * If the pseudowire already exists in the configuration it gets updated.
     *
     * @param tunnelId Id of tunnel
     * @param pwLabel PW label of tunnel
     * @param cP1 Connection point 1
     * @param cP1InnerVlan Inner vlan of cp1
     * @param cP1OuterVlan Outer vlan of cp2
     * @param cP2 Connection point 2
     * @param cP2InnerVlan Inner vlan of cp2
     * @param cP2OuterVlan Outer vlan of cp2
     * @param mode Mode for the pw
     * @param sdTag Service delimiting tag for the pw
     * @return The ObjectNode config if configuration is valid with the new pseudowire
     * or null.
     */
    public ObjectNode addPseudowire(String tunnelId, String pwLabel, String cP1,
                                    String cP1InnerVlan, String cP1OuterVlan, String cP2,
                                    String cP2InnerVlan, String cP2OuterVlan,
                                    String mode, String sdTag) {


        ObjectNode newPw = new ObjectNode(JsonNodeFactory.instance);

        // add fields for pseudowire
        newPw.put(SRC_CP, cP1);
        newPw.put(DST_CP, cP2);
        newPw.put(PW_LABEL, pwLabel);
        newPw.put(SRC_INNER_TAG, cP1InnerVlan);
        newPw.put(SRC_OUTER_TAG, cP1OuterVlan);
        newPw.put(DST_INNER_TAG, cP2InnerVlan);
        newPw.put(DST_OUTER_TAG, cP2OuterVlan);
        newPw.put(SD_TAG, sdTag);
        newPw.put(MODE, mode);

        object.set(tunnelId, newPw);

        if (!isValid()) {
            log.info("Pseudowire could not be created : {}");
            object.remove(tunnelId);
            return null;
        }

        return object;
    }
}
