/*
 * Copyright 2018-present Open Networking Foundation
 *
 * 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.openstacknode.codec;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.packet.IpAddress;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.ControllerInfo;
import org.onosproject.openstacknode.api.DefaultOpenstackNode;
import org.onosproject.openstacknode.api.DpdkConfig;
import org.onosproject.openstacknode.api.NodeState;
import org.onosproject.openstacknode.api.OpenstackAuth;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackPhyInterface;
import org.onosproject.openstacknode.api.OpenstackSshAuth;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
import static org.onosproject.openstacknode.api.Constants.CONTROLLER;
import static org.onosproject.openstacknode.api.Constants.DATA_IP;
import static org.onosproject.openstacknode.api.Constants.GATEWAY;
import static org.onosproject.openstacknode.api.Constants.HOST_NAME;
import static org.onosproject.openstacknode.api.Constants.MANAGEMENT_IP;
import static org.onosproject.openstacknode.api.Constants.UPLINK_PORT;
import static org.onosproject.openstacknode.api.Constants.VLAN_INTF_NAME;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Openstack node codec used for serializing and de-serializing JSON string.
 */
public final class OpenstackNodeCodec extends JsonCodec<OpenstackNode> {

    private final Logger log = getLogger(getClass());

    private static final String TYPE = "type";
    private static final String INTEGRATION_BRIDGE = "integrationBridge";
    private static final String STATE = "state";
    private static final String PHYSICAL_INTERFACES = "phyIntfs";
    private static final String CONTROLLERS = "controllers";
    private static final String AUTHENTICATION = "authentication";
    private static final String END_POINT = "endpoint";
    private static final String SSH_AUTH = "sshAuth";
    private static final String DPDK_CONFIG = "dpdkConfig";

    private static final String MISSING_MESSAGE = " is required in OpenstackNode";

    @Override
    public ObjectNode encode(OpenstackNode node, CodecContext context) {
        checkNotNull(node, "Openstack node cannot be null");

        ObjectNode result = context.mapper().createObjectNode()
                .put(HOST_NAME, node.hostname())
                .put(TYPE, node.type().name())
                .put(STATE, node.state().name())
                .put(MANAGEMENT_IP, node.managementIp().toString());

        OpenstackNode.NodeType type = node.type();

        if (type == OpenstackNode.NodeType.GATEWAY) {
            result.put(UPLINK_PORT, node.uplinkPort());
        }

        if (type == OpenstackNode.NodeType.CONTROLLER) {
            result.put(END_POINT, node.endpoint());
        }

        if (node.intgBridge() != null) {
            result.put(INTEGRATION_BRIDGE, node.intgBridge().toString());
        }

        if (node.vlanIntf() != null) {
            result.put(VLAN_INTF_NAME, node.vlanIntf());
        }

        if (node.dataIp() != null) {
            result.put(DATA_IP, node.dataIp().toString());
        }

        // TODO: need to find a way to not refer to ServiceDirectory from
        // DefaultOpenstackNode

        ArrayNode phyIntfs = context.mapper().createArrayNode();
        node.phyIntfs().forEach(phyIntf -> {
            ObjectNode phyIntfJson = context.codec(OpenstackPhyInterface.class).encode(phyIntf, context);
            phyIntfs.add(phyIntfJson);
        });
        result.set(PHYSICAL_INTERFACES, phyIntfs);

        ArrayNode controllers = context.mapper().createArrayNode();
        node.controllers().forEach(controller -> {
            ObjectNode controllerJson = context.codec(ControllerInfo.class).encode(controller, context);
            controllers.add(controllerJson);
        });

        if (node.authentication() != null) {
            ObjectNode authJson = context.codec(OpenstackAuth.class)
                    .encode(node.authentication(), context);
            result.set(AUTHENTICATION, authJson);
        }

        if (node.sshAuthInfo() != null) {
            ObjectNode sshAuthJson = context.codec(OpenstackSshAuth.class)
                    .encode(node.sshAuthInfo(), context);
            result.set(SSH_AUTH, sshAuthJson);
        }

        if (node.dpdkConfig() != null) {
            ObjectNode dpdkConfigJson = context.codec(DpdkConfig.class)
                    .encode(node.dpdkConfig(), context);
            result.set(DPDK_CONFIG, dpdkConfigJson);
        }

        return result;
    }

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

        String hostname = nullIsIllegal(json.get(HOST_NAME).asText(),
                HOST_NAME + MISSING_MESSAGE);
        String type = nullIsIllegal(json.get(TYPE).asText(),
                TYPE + MISSING_MESSAGE);
        String mIp = nullIsIllegal(json.get(MANAGEMENT_IP).asText(),
                MANAGEMENT_IP + MISSING_MESSAGE);

        DefaultOpenstackNode.Builder nodeBuilder = DefaultOpenstackNode.builder()
                .hostname(hostname)
                .type(OpenstackNode.NodeType.valueOf(type))
                .state(NodeState.INIT)
                .managementIp(IpAddress.valueOf(mIp));

        if (type.equals(GATEWAY)) {
            nodeBuilder.uplinkPort(nullIsIllegal(json.get(UPLINK_PORT).asText(),
                    UPLINK_PORT + MISSING_MESSAGE));
        }
        if (type.equals(CONTROLLER)) {
            String endPoint = nullIsIllegal(json.get(END_POINT).asText(),
                    END_POINT + MISSING_MESSAGE);
            nodeBuilder.endpoint(endPoint);
        }
        if (json.get(VLAN_INTF_NAME) != null) {
            nodeBuilder.vlanIntf(json.get(VLAN_INTF_NAME).asText());
        }
        if (json.get(DATA_IP) != null) {
            nodeBuilder.dataIp(IpAddress.valueOf(json.get(DATA_IP).asText()));
        }

        JsonNode intBridgeJson = json.get(INTEGRATION_BRIDGE);
        if (intBridgeJson != null) {
            nodeBuilder.intgBridge(DeviceId.deviceId(intBridgeJson.asText()));
        }

        // parse physical interfaces
        List<OpenstackPhyInterface> phyIntfs = new ArrayList<>();
        JsonNode phyIntfsJson = json.get(PHYSICAL_INTERFACES);
        if (phyIntfsJson != null) {

            final JsonCodec<OpenstackPhyInterface>
                    phyIntfCodec = context.codec(OpenstackPhyInterface.class);

            IntStream.range(0, phyIntfsJson.size()).forEach(i -> {
                ObjectNode intfJson = get(phyIntfsJson, i);
                phyIntfs.add(phyIntfCodec.decode(intfJson, context));
            });
        }
        nodeBuilder.phyIntfs(phyIntfs);

        // parse customized controllers
        List<ControllerInfo> controllers = new ArrayList<>();
        JsonNode controllersJson = json.get(CONTROLLERS);
        if (controllersJson != null) {

            final JsonCodec<ControllerInfo>
                    controllerCodec = context.codec(ControllerInfo.class);

            IntStream.range(0, controllersJson.size()).forEach(i -> {
                ObjectNode controllerJson = get(controllersJson, i);
                controllers.add(controllerCodec.decode(controllerJson, context));
            });
        }
        nodeBuilder.controllers(controllers);

        // parse authentication
        JsonNode authJson = json.get(AUTHENTICATION);
        if (authJson != null) {

            final JsonCodec<OpenstackAuth> authCodec = context.codec(OpenstackAuth.class);

            OpenstackAuth auth = authCodec.decode((ObjectNode) authJson.deepCopy(), context);
            nodeBuilder.authentication(auth);
        }

        // parse ssh authentication
        JsonNode sshAuthJson = json.get(SSH_AUTH);
        if (sshAuthJson != null) {
            final JsonCodec<OpenstackSshAuth> sshAuthJsonCodec = context.codec(OpenstackSshAuth.class);

            OpenstackSshAuth sshAuth = sshAuthJsonCodec.decode((ObjectNode) sshAuthJson.deepCopy(), context);
            nodeBuilder.sshAuthInfo(sshAuth);
        }

        JsonNode dpdkConfigJson = json.get(DPDK_CONFIG);
        if (dpdkConfigJson != null) {
            final JsonCodec<DpdkConfig> dpdkConfigJsonCodec = context.codec(DpdkConfig.class);

            DpdkConfig dpdkConfig = dpdkConfigJsonCodec.decode((ObjectNode) dpdkConfigJson.deepCopy(), context);
            nodeBuilder.dpdkConfig(dpdkConfig);
        }

        log.trace("node is {}", nodeBuilder.build().toString());

        return nodeBuilder.build();
    }
}
