/*
 * Copyright 2021-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.kubevirtnetworking.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.kubevirtnetworking.api.DefaultKubevirtNetwork;
import org.onosproject.kubevirtnetworking.api.KubevirtHostRoute;
import org.onosproject.kubevirtnetworking.api.KubevirtIpPool;
import org.onosproject.kubevirtnetworking.api.KubevirtNetwork;
import org.slf4j.Logger;

import java.util.HashSet;
import java.util.Set;
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;

/**
 * Kubevirt network codec used for serializing and de-serializing JSON string.
 */
public final class KubevirtNetworkCodec extends JsonCodec<KubevirtNetwork> {

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

    private static final String NETWORK_ID = "networkId";
    private static final String TYPE = "type";
    private static final String NAME = "name";
    private static final String MTU = "mtu";
    private static final String SEGMENT_ID = "segmentId";
    private static final String GATEWAY_IP = "gatewayIp";
    private static final String CIDR = "cidr";
    private static final String HOST_ROUTES = "hostRoutes";
    private static final String IP_POOL = "ipPool";

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

    @Override
    public ObjectNode encode(KubevirtNetwork network, CodecContext context) {
        checkNotNull(network, "Kubevirt network cannot be null");

        ObjectNode result = context.mapper().createObjectNode()
                .put(NETWORK_ID, network.networkId())
                .put(TYPE, network.type().name())
                .put(NAME, network.name())
                .put(MTU, network.mtu())
                .put(GATEWAY_IP, network.gatewayIp().toString())
                .put(CIDR, network.cidr());

        if (network.segmentId() != null) {
            result.put(SEGMENT_ID, network.segmentId());
        }

        if (network.hostRoutes() != null && !network.hostRoutes().isEmpty()) {
            ArrayNode hostRoutes = context.mapper().createArrayNode();
            network.hostRoutes().forEach(hostRoute -> {
                ObjectNode hostRouteJson =
                        context.codec(KubevirtHostRoute.class).encode(hostRoute, context);
                hostRoutes.add(hostRouteJson);
            });
            result.set(HOST_ROUTES, hostRoutes);
        }

        if (network.ipPool() != null) {
            ObjectNode ipPoolJson = context.codec(KubevirtIpPool.class).encode(network.ipPool(), context);
            result.set(IP_POOL, ipPoolJson);
        }

        return result;
    }

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

        String networkId = nullIsIllegal(json.get(NETWORK_ID).asText(),
                NETWORK_ID + MISSING_MESSAGE);
        String type = nullIsIllegal(json.get(TYPE).asText(),
                TYPE + MISSING_MESSAGE);
        String name = nullIsIllegal(json.get(NAME).asText(),
                NAME + MISSING_MESSAGE);
        Integer mtu = nullIsIllegal(json.get(MTU).asInt(),
                MTU + MISSING_MESSAGE);
        String gatewayIp = nullIsIllegal(json.get(GATEWAY_IP).asText(),
                GATEWAY_IP + MISSING_MESSAGE);
        String cidr = nullIsIllegal(json.get(CIDR).asText(),
                CIDR + MISSING_MESSAGE);

        KubevirtNetwork.Builder networkBuilder = DefaultKubevirtNetwork.builder()
                .networkId(networkId)
                .type(KubevirtNetwork.Type.valueOf(type))
                .name(name)
                .mtu(mtu)
                .gatewayIp(IpAddress.valueOf(gatewayIp))
                .cidr(cidr);

        JsonNode ipPoolJson = json.get(IP_POOL);
        if (ipPoolJson != null) {
            final JsonCodec<KubevirtIpPool>
                    ipPoolCodec = context.codec(KubevirtIpPool.class);
            networkBuilder.ipPool(ipPoolCodec.decode(
                    (ObjectNode) ipPoolJson.deepCopy(), context));
        }

        // parse host routes
        Set<KubevirtHostRoute> hostRoutes = new HashSet<>();
        JsonNode hostRoutesJson = json.get(HOST_ROUTES);
        if (hostRoutesJson != null) {
            final JsonCodec<KubevirtHostRoute>
                    hostRouteCodec = context.codec(KubevirtHostRoute.class);

            IntStream.range(0, hostRoutesJson.size()).forEach(i -> {
                ObjectNode routeJson = get(hostRoutesJson, i);
                hostRoutes.add(hostRouteCodec.decode(routeJson, context));
            });
        }
        networkBuilder.hostRoutes(hostRoutes);

        log.trace("Network is {}", networkBuilder.build().toString());

        return networkBuilder.build();
    }
}
