/*
 * 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.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.intent.ConnectivityIntent;
import org.onosproject.net.intent.PointToPointIntent;

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

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

/**
 * Point to point intent codec.
 */
public final class PointToPointIntentCodec extends JsonCodec<PointToPointIntent> {

    private static final String INGRESS_POINT = "ingressPoint";
    private static final String EGRESS_POINT = "egressPoint";

    @Override
    public ObjectNode encode(PointToPointIntent intent, CodecContext context) {
        checkNotNull(intent, "Point to 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 egress =
                connectPointCodec.encode(intent.egressPoint(), context);

        result.set(INGRESS_POINT, ingress);
        result.set(EGRESS_POINT, egress);

        return result;
    }


    @Override
    public PointToPointIntent decode(ObjectNode json, CodecContext context) {
        PointToPointIntent.Builder builder = PointToPointIntent.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.ingressPoint(ingress);

        ObjectNode egressJson = nullIsIllegal(get(json, EGRESS_POINT),
                EGRESS_POINT + IntentCodec.MISSING_MEMBER_MESSAGE);
        ConnectPoint egress = context.codec(ConnectPoint.class)
                .decode(egressJson, context);
        builder.egressPoint(egress);

        return builder.build();
    }
}
