/*
 * 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.vtnweb.web;


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

import java.util.List;
import java.util.UUID;

import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.DefaultPortChain;
import org.onosproject.vtnrsc.FlowClassifierId;
import org.onosproject.vtnrsc.PortChain;
import org.onosproject.vtnrsc.PortChainId;
import org.onosproject.vtnrsc.PortPairGroupId;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Lists;

/**
 * Port chain JSON codec.
 */
public final class PortChainCodec extends JsonCodec<PortChain> {

    private static final String ID = "id";
    private static final String TENANT_ID = "tenant_id";
    private static final String NAME = "name";
    private static final String DESCRIPTION = "description";
    private static final String PORT_PAIR_GROUPS = "port_pair_groups";
    private static final String FLOW_CLASSIFIERS = "flow_classifiers";
    private static final String MISSING_MEMBER_MESSAGE =
            " member is required in PortChain";

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

        PortChain.Builder resultBuilder = new DefaultPortChain.Builder();

        String id = nullIsIllegal(json.get(ID),
                                  ID + MISSING_MEMBER_MESSAGE).asText();
        resultBuilder.setId(PortChainId.portChainId(id));

        String tenantId = nullIsIllegal(json.get(TENANT_ID),
                                        TENANT_ID + MISSING_MEMBER_MESSAGE).asText();
        resultBuilder.setTenantId(TenantId.tenantId(tenantId));

        String name = nullIsIllegal(json.get(NAME),
                                    NAME + MISSING_MEMBER_MESSAGE).asText();
        resultBuilder.setName(name);

        String description = nullIsIllegal(json.get(DESCRIPTION),
                                           DESCRIPTION + MISSING_MEMBER_MESSAGE).asText();
        resultBuilder.setDescription(description);

        ArrayNode arrayNode = (ArrayNode) json.path(PORT_PAIR_GROUPS);
        if (arrayNode != null) {
            List<PortPairGroupId> list = Lists.newArrayList();
            arrayNode.forEach(i -> list.add(PortPairGroupId.portPairGroupId(i.asText())));
            resultBuilder.setPortPairGroups(list);
        }

        arrayNode = (ArrayNode) json.path(FLOW_CLASSIFIERS);
        if (arrayNode != null) {
            List<FlowClassifierId> list = Lists.newArrayList();
            arrayNode.forEach(i -> list.add(FlowClassifierId.of(UUID.fromString(i.asText()))));
            resultBuilder.setFlowClassifiers(list);
        }

        return resultBuilder.build();
    }

    @Override
    public ObjectNode encode(PortChain portChain, CodecContext context) {
        checkNotNull(portChain, "port pair cannot be null");
        ObjectNode result = context.mapper().createObjectNode()
                .put(ID, portChain.portChainId().toString())
                .put(TENANT_ID, portChain.tenantId().toString())
                .put(NAME, portChain.name())
                .put(DESCRIPTION, portChain.description())
                .put(PORT_PAIR_GROUPS, portChain.portPairGroups().toString())
                .put(FLOW_CLASSIFIERS, portChain.flowClassifiers().toString());
        return result;
    }
}
