/*
 * Copyright 2016 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 com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flowobjective.DefaultFilteringObjective;
import org.onosproject.net.flowobjective.FilteringObjective;
import org.slf4j.Logger;

import java.util.stream.IntStream;

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

/**
 * Filtering Objective Codec.
 */
public class FilteringObjectiveCodec extends JsonCodec<FilteringObjective> {
    private final Logger log = getLogger(getClass());

    // JSON field names
    private static final String ID = "id";
    private static final String TYPE = "type";
    private static final String KEY = "key";
    private static final String META = "meta";
    private static final String OPERATION = "operation";
    private static final String CONDITIONS = "conditions";

    // messages to be printed out
    private static final String MISSING_MEMBER_MESSAGE =
            " member is required in FilteringObjective";
    private static final String NOT_NULL_MESSAGE =
            "FilteringObjective cannot be null";
    private static final String INVALID_TYPE_MESSAGE =
            "The requested type {} is not defined in FilteringObjective.";
    private static final String INVALID_OP_MESSAGE =
            "The requested operation {} is not defined for FilteringObjective.";

    public static final String REST_APP_ID = "org.onosproject.rest";

    @Override
    public ObjectNode encode(FilteringObjective filteringObjective, CodecContext context) {

        checkNotNull(filteringObjective, NOT_NULL_MESSAGE);

        final JsonCodec<Criterion> criterionCodec = context.codec(Criterion.class);
        final JsonCodec<TrafficTreatment> trafficTreatmentCodec = context.codec(TrafficTreatment.class);

        // encode common properties
        ObjectiveCodecHelper och = new ObjectiveCodecHelper();
        ObjectNode result = och.encode(filteringObjective, context);

        // encode id
        result.put(ID, filteringObjective.id());

        // encode type
        result.put(TYPE, filteringObjective.type().toString());

        // encode key
        if (filteringObjective.key() != null) {
            ObjectNode criterionNode = criterionCodec.encode(filteringObjective.key(), context);
            result.set(KEY, criterionNode);
        }

        // encode meta
        if (filteringObjective.meta() != null) {
            ObjectNode trafficTreatmentNode = trafficTreatmentCodec.encode(filteringObjective.meta(), context);
            result.set(META, trafficTreatmentNode);
        }

        // encode conditions
        ArrayNode conditions = context.mapper().createArrayNode();
        filteringObjective.conditions().forEach(c -> {
            ObjectNode criterionJson = criterionCodec.encode(c, context);
            conditions.add(criterionJson);
        });
        result.set(CONDITIONS, conditions);

        return result;
    }

    @Override
    public FilteringObjective decode(ObjectNode json, CodecContext context) {
        if (json == null || !json.isObject()) {
            return null;
        }

        CoreService coreService = context.getService(CoreService.class);

        final JsonCodec<Criterion> criterionCodec = context.codec(Criterion.class);
        final JsonCodec<TrafficTreatment> trafficTreatmentCodec = context.codec(TrafficTreatment.class);

        ObjectiveCodecHelper och = new ObjectiveCodecHelper();

        DefaultFilteringObjective.Builder baseBuilder = DefaultFilteringObjective.builder();
        final DefaultFilteringObjective.Builder builder =
                (DefaultFilteringObjective.Builder) och.decode(json, baseBuilder, context);

        // application id
        ApplicationId appId = coreService.registerApplication(REST_APP_ID);
        builder.fromApp(appId);

        // decode type
        String typeStr = nullIsIllegal(json.get(TYPE), TYPE + MISSING_MEMBER_MESSAGE).asText();

        switch (typeStr) {
            case "PERMIT":
                builder.permit();
                break;
            case "DENY":
                builder.deny();
                break;
            default:
                log.warn(INVALID_TYPE_MESSAGE, typeStr);
                return null;
        }

        // decode key
        JsonNode keyJson = json.get(KEY);
        if (keyJson != null) {
            Criterion key = criterionCodec.decode((ObjectNode) keyJson, context);
            builder.withKey(key);
        }

        // decode conditions
        JsonNode conditionsJson = json.get(CONDITIONS);
        checkNotNull(conditionsJson);
        if (conditionsJson != null) {
            IntStream.range(0, conditionsJson.size()).forEach(i -> {
                ObjectNode conditionJson = get(conditionsJson, i);
                builder.addCondition(criterionCodec.decode(conditionJson, context));
            });
        }

        // decode meta
        JsonNode metaJson = json.get(META);
        if (metaJson != null) {
            TrafficTreatment trafficTreatment = trafficTreatmentCodec.decode((ObjectNode) metaJson, context);
            builder.withMeta(trafficTreatment);
        }

        // decode operation
        String opStr = nullIsIllegal(json.get(OPERATION), OPERATION + MISSING_MEMBER_MESSAGE).asText();
        FilteringObjective filteringObjective;

        switch (opStr) {
            case "ADD":
                filteringObjective = builder.add();
                break;
            case "REMOVE":
                filteringObjective = builder.remove();
                break;
            default:
                log.warn(INVALID_OP_MESSAGE, opStr);
                return null;
        }

        return filteringObjective;
    }
}
