/*
 * 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.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.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flowobjective.DefaultForwardingObjective;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.slf4j.Logger;

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

/**
 * Forwarding Objective Codec.
 */
public class ForwardingObjectiveCodec extends JsonCodec<ForwardingObjective> {
    private final Logger log = getLogger(getClass());

    // JSON field names
    private static final String ID = "id";
    private static final String SELECTOR = "selector";
    private static final String FLAG = "flag";
    private static final String OPERATION = "operation";
    private static final String NEXT_ID = "nextId";
    private static final String TREATMENT = "treatment";

    // messages to be printed out
    private static final String MISSING_MEMBER_MESSAGE =
            " member is required in ForwardingObjective";
    private static final String NOT_NULL_MESSAGE =
            "ForwardingObjective cannot be null";
    private static final String INVALID_FLAG_MESSAGE =
            "The requested flag {} is not defined in ForwardingObjective.";
    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(ForwardingObjective forwardingObjective, CodecContext context) {

        checkNotNull(forwardingObjective, NOT_NULL_MESSAGE);

        final JsonCodec<TrafficTreatment> trafficTreatmentCodec = context.codec(TrafficTreatment.class);
        final JsonCodec<TrafficSelector> trafficSelectorCodec = context.codec(TrafficSelector.class);

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

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

        // encode flag
        result.put(FLAG, forwardingObjective.flag().toString());

        // encode op
        result.put(OPERATION, forwardingObjective.op().toString());

        // encode selector
        ObjectNode trafficSelectorNode =
                trafficSelectorCodec.encode(forwardingObjective.selector(), context);
        result.set(SELECTOR, trafficSelectorNode);

        // encode nextId
        if (forwardingObjective.nextId() != null) {
            result.put(NEXT_ID, forwardingObjective.nextId());
        }

        // encode treatment
        if (forwardingObjective.treatment() != null) {
            ObjectNode trafficTreatmentNode =
                    trafficTreatmentCodec.encode(forwardingObjective.treatment(), context);
            result.set(TREATMENT, trafficTreatmentNode);
        }

        return result;
    }

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

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

        final JsonCodec<TrafficTreatment> trafficTreatmentCodec = context.codec(TrafficTreatment.class);
        final JsonCodec<TrafficSelector> trafficSelectorCodec = context.codec(TrafficSelector.class);

        ObjectiveCodecHelper och = new ObjectiveCodecHelper();

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

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

        // decode flag
        String flagStr = nullIsIllegal(json.get(FLAG), FLAG + MISSING_MEMBER_MESSAGE).asText();
        switch (flagStr) {
            case "SPECIFIC":
                builder.withFlag(ForwardingObjective.Flag.SPECIFIC);
                break;
            case "VERSATILE":
                builder.withFlag(ForwardingObjective.Flag.VERSATILE);
                break;
            default:
                log.warn(INVALID_FLAG_MESSAGE, flagStr);
                return null;
        }

        // decode selector
        JsonNode selectorJson = json.get(SELECTOR);
        if (selectorJson != null) {
            TrafficSelector trafficSelector = trafficSelectorCodec.decode((ObjectNode) selectorJson, context);
            builder.withSelector(trafficSelector);
        }

        // decode treatment
        JsonNode treatmentJson = json.get(TREATMENT);
        if (treatmentJson != null) {
            TrafficTreatment trafficTreatment = trafficTreatmentCodec.decode((ObjectNode) treatmentJson, context);
            builder.withTreatment(trafficTreatment);
        }

        // decode nextId
        JsonNode nextIdJson = json.get(NEXT_ID);
        if (nextIdJson != null) {
            builder.nextStep(nextIdJson.asInt());
        }

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

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

        return forwardingObjective;
    }
}
