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

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.FilteredConnectPoint;
import org.onosproject.net.intent.ConnectivityIntent;
import org.onosproject.net.intent.SinglePointToMultiPointIntent;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.util.HashSet;
import java.util.Set;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;

/**
 * Single Point to Multi Point intent codec.
 */
public class SinglePointToMultiPointIntentCodec extends JsonCodec<SinglePointToMultiPointIntent> {
    private static final String INGRESS_POINT = "ingressPoint";
    private static final String EGRESS_POINT = "egressPoint";
    private static final String CP_POINTS = "connectPoints";

    @Override
    public ObjectNode encode(SinglePointToMultiPointIntent intent, CodecContext context) {
        checkNotNull(intent, "Single Point to Multi Point intent cannot be null");

        final JsonCodec<ConnectivityIntent> connectivityIntentCodec =
                context.codec(ConnectivityIntent.class);
        final ObjectNode result = connectivityIntentCodec.encode(intent, context);

        final JsonCodec<ConnectPoint> connectPointCodec =
                context.codec(ConnectPoint.class);
        final ObjectNode ingress =
                connectPointCodec.encode(intent.ingressPoint(), context);

        final ObjectNode result2 = context.mapper().createObjectNode();
        final ArrayNode jsonconnectPoints = result2.putArray(CP_POINTS);

        if (intent.egressPoints() != null) {
            for (final ConnectPoint cp : intent.egressPoints()) {
                jsonconnectPoints.add(connectPointCodec.encode(cp, context));
            }
            result.set(EGRESS_POINT, jsonconnectPoints);
        }
        result.set(INGRESS_POINT, ingress);

        return result;
    }

    @Override
    public SinglePointToMultiPointIntent decode(ObjectNode json, CodecContext context) {
        SinglePointToMultiPointIntent.Builder builder = SinglePointToMultiPointIntent.builder();

        IntentCodec.intentAttributes(json, context, builder);
        ConnectivityIntentCodec.intentAttributes(json, context, builder);

        ObjectNode ingressJson = nullIsIllegal(get(json, INGRESS_POINT),
                INGRESS_POINT + IntentCodec.MISSING_MEMBER_MESSAGE);
        ConnectPoint ingress = context.codec(ConnectPoint.class)
                .decode(ingressJson, context);
        builder.filteredIngressPoint(new FilteredConnectPoint(ingress));

        ObjectNode egressJson = nullIsIllegal(get(json, EGRESS_POINT),
                EGRESS_POINT + IntentCodec.MISSING_MEMBER_MESSAGE);
        if (egressJson != null) {
            final JsonCodec<ConnectPoint> connectPointCodec =
                    context.codec(ConnectPoint.class);
            JsonNode connectPointsJson = get(json, EGRESS_POINT).get(CP_POINTS);

            Set<FilteredConnectPoint> egressCp = new HashSet<>();
            if (connectPointsJson != null) {
                for (int i = 0; i < connectPointsJson.size(); i++) {
                    ConnectPoint cp = connectPointCodec.decode(get(connectPointsJson, i), context);
                    egressCp.add(new FilteredConnectPoint(cp));
                }
                builder.filteredEgressPoints(egressCp);
            }
        }

        return builder.build();
    }
}

@@ -686,20 +686,26 @@
 atabind.
-Json
+node.Array
 Node;%0Aim
@@ -737,37 +737,38 @@
 n.databind.node.
-Array
+Object
 Node;%0Aimport org
@@ -1052,63 +1052,8 @@
 ent;
-%0Aimport com.fasterxml.jackson.databind.node.ObjectNode;
 %0A%0Aim
@@ -1496,69 +1496,8 @@
 nt%22;
-%0A    private static final String CP_POINTS = %22connectPoints%22;
 %0A%0A  
@@ -2131,136 +2131,71 @@
 nal 
-ObjectNode result2 = context.mapper().createObjectNode();%0A        final ArrayNode jsonconnectPoints = result2.putArray(CP_POINTS
+ArrayNode jsonconnectPoints = context.mapper().createArrayNode(
 );%0A%0A
@@ -3209,30 +3209,29 @@
 );%0A%0A        
-Object
+Array
 Node egressJ
@@ -3250,26 +3250,37 @@
 Illegal(
-get(json, 
+(ArrayNode) json.get(
 EGRESS_P
@@ -3278,36 +3278,32 @@
 (EGRESS_POINT),%0A
-    
             EGRE
@@ -3354,46 +3354,9 @@
 E);%0A
-        if (egressJson != null) %7B%0A    
+%0A
     
@@ -3417,36 +3417,32 @@
                 
-  
-  
 context.codec(Co
@@ -3464,94 +3464,9 @@
 s);%0A
-            JsonNode connectPointsJson = get(json, EGRESS_POINT).get(CP_POINTS);%0A%0A    
+%0A
     
@@ -3527,62 +3527,17 @@
 ();%0A
-            if (connectPointsJson != null) %7B%0A 
+%0A
         
     
@@ -3528,31 +3528,24 @@
 );%0A%0A        
-       
 for (int i =
@@ -3552,28 +3552,21 @@
  0; i %3C 
-connectPoint
+egres
 sJson.si
@@ -3574,32 +3574,24 @@
 e(); i++) %7B%0A
-        
             
@@ -3637,28 +3637,21 @@
 ode(get(
-connectPoint
+egres
 sJson, i
@@ -3663,24 +3663,16 @@
 ntext);%0A
-        
         
@@ -3727,34 +3727,18 @@
         
-   
-     %7D%0A        
+%7D%0A
         
@@ -3780,32 +3780,8 @@
 Cp);
-%0A            %7D%0A        %7D
 %0A%0A  

Fix for ONOS-7960 - single to multi intent json codec can't decode egress point array