/*
 * 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.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.constraint.AnnotationConstraint;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.onosproject.net.intent.constraint.LambdaConstraint;
import org.onosproject.net.intent.constraint.LatencyConstraint;
import org.onosproject.net.intent.constraint.LinkTypeConstraint;
import org.onosproject.net.intent.constraint.ObstacleConstraint;
import org.onosproject.net.intent.constraint.WaypointConstraint;

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

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Implementation of encoder for constraint JSON codec.
 */
public final class EncodeConstraintCodecHelper {

    private final Constraint constraint;
    private final CodecContext context;

    /**
     * Constructs a constraint encoder.
     *
     * @param constraint constraint to encode
     * @param context to use for look ups
     */
    public EncodeConstraintCodecHelper(Constraint constraint, CodecContext context) {
        this.constraint = constraint;
        this.context = context;
    }

    /**
     * Encodes a latency constraint.
     *
     * @return JSON ObjectNode representing the constraint
     */
    private ObjectNode encodeLatencyConstraint() {
        checkNotNull(constraint, "Duration constraint cannot be null");
        final LatencyConstraint latencyConstraint =
                (LatencyConstraint) constraint;
        return context.mapper().createObjectNode()
                .put("latencyMillis", latencyConstraint.latency().toMillis());
    }

    /**
     * Encodes an obstacle constraint.
     *
     * @return JSON ObjectNode representing the constraint
     */
    private ObjectNode encodeObstacleConstraint() {
        checkNotNull(constraint, "Obstacle constraint cannot be null");
        final ObstacleConstraint obstacleConstraint =
                (ObstacleConstraint) constraint;

        final ObjectNode result = context.mapper().createObjectNode();
        final ArrayNode jsonObstacles = result.putArray("obstacles");

        for (DeviceId did : obstacleConstraint.obstacles()) {
            jsonObstacles.add(did.toString());
        }

        return result;
    }

    /**
     * Encodes a waypoint constraint.
     *
     * @return JSON ObjectNode representing the constraint
     */
    private ObjectNode encodeWaypointConstraint() {
        checkNotNull(constraint, "Waypoint constraint cannot be null");
        final WaypointConstraint waypointConstraint =
                (WaypointConstraint) constraint;

        final ObjectNode result = context.mapper().createObjectNode();
        final ArrayNode jsonWaypoints = result.putArray("waypoints");

        for (DeviceId did : waypointConstraint.waypoints()) {
            jsonWaypoints.add(did.toString());
        }

        return result;
    }

    /**
     * Encodes a annotation constraint.
     *
     * @return JSON ObjectNode representing the constraint
     */
    private ObjectNode encodeAnnotationConstraint() {
        checkNotNull(constraint, "Annotation constraint cannot be null");
        final AnnotationConstraint annotationConstraint =
                (AnnotationConstraint) constraint;
        return context.mapper().createObjectNode()
                .put("key", annotationConstraint.key())
                .put("threshold", annotationConstraint.threshold());
    }

    /**
     * Encodes a bandwidth constraint.
     *
     * @return JSON ObjectNode representing the constraint
     */
    private ObjectNode encodeBandwidthConstraint() {
        checkNotNull(constraint, "Bandwidth constraint cannot be null");
        final BandwidthConstraint bandwidthConstraint =
                (BandwidthConstraint) constraint;
        return context.mapper().createObjectNode()
                .put("bandwidth", bandwidthConstraint.bandwidth().bps());
    }

    /**
     * Encodes a lambda constraint.
     *
     * @return JSON ObjectNode representing the constraint
     */
    private ObjectNode encodeLambdaConstraint() {
        checkNotNull(constraint, "Lambda constraint cannot be null");
        final LambdaConstraint lambdaConstraint =
                (LambdaConstraint) constraint;

        return context.mapper().createObjectNode()
                .put("lambda", lambdaConstraint.lambda().toInt());
    }

    /**
     * Encodes a link type constraint.
     *
     * @return JSON ObjectNode representing the constraint
     */
    private ObjectNode encodeLinkTypeConstraint() {
        checkNotNull(constraint, "Link type constraint cannot be null");

        final LinkTypeConstraint linkTypeConstraint =
                (LinkTypeConstraint) constraint;

        final ObjectNode result = context.mapper().createObjectNode()
                .put(ConstraintCodec.INCLUSIVE, linkTypeConstraint.isInclusive());

        final ArrayNode jsonTypes = result.putArray(ConstraintCodec.TYPES);

        if (linkTypeConstraint.types() != null) {
            for (Link.Type type : linkTypeConstraint.types()) {
                jsonTypes.add(type.name());
            }
        }

        return result;
    }

    /**
     * Encodes the constraint in JSON.
     *
     * @return JSON node
     */
    public ObjectNode encode() {
        final ObjectNode result;
        if (constraint instanceof BandwidthConstraint) {
            result = encodeBandwidthConstraint();
        } else if (constraint instanceof LambdaConstraint) {
            result = encodeLambdaConstraint();
        } else if (constraint instanceof LinkTypeConstraint) {
            result = encodeLinkTypeConstraint();
        } else if (constraint instanceof AnnotationConstraint) {
            result = encodeAnnotationConstraint();
        } else if (constraint instanceof LatencyConstraint) {
            result = encodeLatencyConstraint();
        } else if (constraint instanceof ObstacleConstraint) {
            result = encodeObstacleConstraint();
        } else if (constraint instanceof WaypointConstraint) {
            result = encodeWaypointConstraint();
        } else {
            result = context.mapper().createObjectNode();
        }

        result.put(ConstraintCodec.TYPE, constraint.getClass().getSimpleName());
        return result;
    }
}
