/*
 * 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 java.time.Duration;
import java.util.ArrayList;
import java.util.stream.IntStream;

import org.onlab.util.Bandwidth;
import org.onosproject.net.DeviceId;
import org.onosproject.net.IndexedLambda;
import org.onosproject.net.Link;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.constraint.AnnotationConstraint;
import org.onosproject.net.intent.constraint.AsymmetricPathConstraint;
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 org.onosproject.net.resource.link.LambdaResource;

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

import static org.onlab.util.Tools.nullIsIllegal;

/**
 * Constraint JSON decoder.
 */
public final class DecodeConstraintCodecHelper {
    private final ObjectNode json;

    /**
     * Constructs a constraint decoder.
     *
     * @param json object node to decode
     */
    public DecodeConstraintCodecHelper(ObjectNode json) {
        this.json = json;
    }

    /**
     * Decodes a link type constraint.
     *
     * @return link type constraint object.
     */
    private Constraint decodeLinkTypeConstraint() {
        boolean inclusive = nullIsIllegal(json.get(ConstraintCodec.INCLUSIVE),
                ConstraintCodec.INCLUSIVE + ConstraintCodec.MISSING_MEMBER_MESSAGE).asBoolean();

        JsonNode types = nullIsIllegal(json.get(ConstraintCodec.TYPES),
                ConstraintCodec.TYPES + ConstraintCodec.MISSING_MEMBER_MESSAGE);
        if (types.size() < 1) {
            throw new IllegalArgumentException(
                    "types array in link constraint must have at least one value");
        }

        ArrayList<Link.Type> typesEntries = new ArrayList<>(types.size());
        IntStream.range(0, types.size())
                .forEach(index ->
                        typesEntries.add(Link.Type.valueOf(types.get(index).asText())));

        return new LinkTypeConstraint(inclusive,
                typesEntries.toArray(new Link.Type[types.size()]));
    }

    /**
     * Decodes an annotation constraint.
     *
     * @return annotation constraint object.
     */
    private Constraint decodeAnnotationConstraint() {
        String key = nullIsIllegal(json.get(ConstraintCodec.KEY),
                ConstraintCodec.KEY + ConstraintCodec.MISSING_MEMBER_MESSAGE)
                .asText();
        double threshold = nullIsIllegal(json.get(ConstraintCodec.THRESHOLD),
                ConstraintCodec.THRESHOLD + ConstraintCodec.MISSING_MEMBER_MESSAGE)
                .asDouble();

        return new AnnotationConstraint(key, threshold);
    }

    /**
     * Decodes a lambda constraint.
     *
     * @return lambda constraint object.
     */
    private Constraint decodeLambdaConstraint() {
        long lambda = nullIsIllegal(json.get(ConstraintCodec.LAMBDA),
                ConstraintCodec.LAMBDA + ConstraintCodec.MISSING_MEMBER_MESSAGE)
                .asLong();

        return new LambdaConstraint(LambdaResource.valueOf(new IndexedLambda(lambda)));
    }

    /**
     * Decodes a latency constraint.
     *
     * @return latency constraint object.
     */
    private Constraint decodeLatencyConstraint() {
        long latencyMillis = nullIsIllegal(json.get(ConstraintCodec.LATENCY_MILLIS),
                ConstraintCodec.LATENCY_MILLIS + ConstraintCodec.MISSING_MEMBER_MESSAGE)
                .asLong();

        return new LatencyConstraint(Duration.ofMillis(latencyMillis));
    }

    /**
     * Decodes an obstacle constraint.
     *
     * @return obstacle constraint object.
     */
    private Constraint decodeObstacleConstraint() {
        JsonNode obstacles = nullIsIllegal(json.get(ConstraintCodec.OBSTACLES),
                ConstraintCodec.OBSTACLES + ConstraintCodec.MISSING_MEMBER_MESSAGE);
        if (obstacles.size() < 1) {
            throw new IllegalArgumentException(
                    "obstacles array in obstacles constraint must have at least one value");
        }

        ArrayList<DeviceId> obstacleEntries = new ArrayList<>(obstacles.size());
        IntStream.range(0, obstacles.size())
                .forEach(index ->
                        obstacleEntries.add(DeviceId.deviceId(obstacles.get(index).asText())));

        return new ObstacleConstraint(
                obstacleEntries.toArray(new DeviceId[obstacles.size()]));
    }

    /**
     * Decodes a waypoint constraint.
     *
     * @return waypoint constraint object.
     */
    private Constraint decodeWaypointConstraint() {
        JsonNode waypoints = nullIsIllegal(json.get(ConstraintCodec.WAYPOINTS),
                ConstraintCodec.WAYPOINTS + ConstraintCodec.MISSING_MEMBER_MESSAGE);
        if (waypoints.size() < 1) {
            throw new IllegalArgumentException(
                    "obstacles array in obstacles constraint must have at least one value");
        }

        ArrayList<DeviceId> waypointEntries = new ArrayList<>(waypoints.size());
        IntStream.range(0, waypoints.size())
                .forEach(index ->
                        waypointEntries.add(DeviceId.deviceId(waypoints.get(index).asText())));

        return new WaypointConstraint(
                waypointEntries.toArray(new DeviceId[waypoints.size()]));
    }

    /**
     * Decodes an asymmetric path constraint.
     *
     * @return asymmetric path constraint object.
     */
    private Constraint decodeAsymmetricPathConstraint() {
        return new AsymmetricPathConstraint();
    }

    /**
     * Decodes a bandwidth constraint.
     *
     * @return bandwidth constraint object.
     */
    private Constraint decodeBandwidthConstraint() {
        double bandwidth = nullIsIllegal(json.get(ConstraintCodec.BANDWIDTH),
                ConstraintCodec.BANDWIDTH + ConstraintCodec.MISSING_MEMBER_MESSAGE)
                .asDouble();

        return new BandwidthConstraint(Bandwidth.bps(bandwidth));
    }

    /**
     * Decodes the given constraint.
     *
     * @return constraint object.
     */
    public Constraint decode() {
        final String type = nullIsIllegal(json.get(ConstraintCodec.TYPE),
                ConstraintCodec.TYPE + ConstraintCodec.MISSING_MEMBER_MESSAGE)
                .asText();

        if (type.equals(BandwidthConstraint.class.getSimpleName())) {
            return decodeBandwidthConstraint();
        } else if (type.equals(LambdaConstraint.class.getSimpleName())) {
            return decodeLambdaConstraint();
        } else if (type.equals(LinkTypeConstraint.class.getSimpleName())) {
            return decodeLinkTypeConstraint();
        } else if (type.equals(AnnotationConstraint.class.getSimpleName())) {
            return decodeAnnotationConstraint();
        } else if (type.equals(LatencyConstraint.class.getSimpleName())) {
            return decodeLatencyConstraint();
        } else if (type.equals(ObstacleConstraint.class.getSimpleName())) {
            return decodeObstacleConstraint();
        } else if (type.equals(WaypointConstraint.class.getSimpleName())) {
            return decodeWaypointConstraint();
        } else if (type.equals(AsymmetricPathConstraint.class.getSimpleName())) {
            return decodeAsymmetricPathConstraint();
        } else if (type.equals(LinkTypeConstraint.class.getSimpleName())) {
            return decodeLinkTypeConstraint();
        } else if (type.equals(AnnotationConstraint.class.getSimpleName())) {
            return decodeAnnotationConstraint();
        }
        throw new IllegalArgumentException("Instruction type "
                + type + " is not supported");
    }
}
