/*
 * Copyright 2015-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.vtnweb.resources;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Maps;
import org.onlab.util.ItemNotFoundException;
import org.onosproject.rest.AbstractWebResource;
import org.onosproject.vtnrsc.DefaultTenantNetwork;
import org.onosproject.vtnrsc.PhysicalNetwork;
import org.onosproject.vtnrsc.SegmentationId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetwork;
import org.onosproject.vtnrsc.TenantNetwork.State;
import org.onosproject.vtnrsc.TenantNetwork.Type;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.service.VtnRscService;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
import org.onosproject.vtnweb.web.TenantNetworkCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static javax.ws.rs.core.Response.Status.OK;
import static org.onlab.util.Tools.readTreeFromStream;

/**
 * REST resource for interacting with the inventory of networks.
 */
@Path("networks")
public class TenantNetworkWebResource extends AbstractWebResource {
    public static final String NETWORK_NOT_FOUND = "Network is not found";
    public static final String NETWORK_ID_EXIST = "Network id is existed";
    public static final String NETWORK_ID_NOT_EXIST = "Network id is not existed";
    public static final String CREATE_NETWORK = "create network";
    public static final String UPDATE_NETWORK = "update network";
    public static final String DELETE_NETWORK = "delete network";
    public static final String JSON_NOT_NULL = "JsonNode can not be null";

    private static final Logger log = LoggerFactory
            .getLogger(TenantNetworkWebResource.class);
    private final ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
            .newConcurrentMap();

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response getNetworks(@QueryParam("id") String queryId,
                                @QueryParam("name") String queryName,
                                @QueryParam("admin_state_up") String queryadminStateUp,
                                @QueryParam("status") String querystate,
                                @QueryParam("shared") String queryshared,
                                @QueryParam("tenant_id") String querytenantId,
                                @QueryParam("router:external") String routerExternal,
                                @QueryParam("provider:network_type") String type,
                                @QueryParam("provider:physical_network") String physicalNetwork,
                                @QueryParam("provider:segmentation_id") String segmentationId) {
        Iterable<TenantNetwork> networks = get(TenantNetworkService.class)
                .getNetworks();
        Iterator<TenantNetwork> networkors = networks.iterator();
        while (networkors.hasNext()) {
            TenantNetwork network = networkors.next();
            if ((queryId == null || queryId.equals(network.id().toString()))
                    && (queryName == null || queryName.equals(network.name()))
                    && (queryadminStateUp == null || queryadminStateUp
                            .equals(Boolean.toString(network.adminStateUp())))
                    && (querystate == null || querystate.equals(network.state()
                            .toString()))
                    && (queryshared == null || queryshared.equals(Boolean.toString(network
                            .shared())))
                    && (querytenantId == null || querytenantId.equals(network
                            .tenantId().toString()))
                    && (routerExternal == null || routerExternal.equals(Boolean.toString(network
                    .routerExternal())))
                    && (type == null || type.equals(network.type().toString()))
                    && (physicalNetwork == null || physicalNetwork
                    .equals(network.physicalNetwork().toString()))
                    && (segmentationId == null || segmentationId.equals(network
                            .segmentationId().toString()))) {
                networksMap.putIfAbsent(network.id(), network);
            }
        }
        networks = Collections.unmodifiableCollection(networksMap.values());
        ObjectNode result = new ObjectMapper().createObjectNode();
        result.set("networks", new TenantNetworkCodec().encode(networks, this));

        return ok(result.toString()).build();
    }

    private State isState(String state) {
        if ("ACTIVE".equals(state)) {
            return TenantNetwork.State.ACTIVE;
        } else if ("BUILD".equals(state)) {
            return TenantNetwork.State.BUILD;
        } else if ("DOWN".equals(state)) {
            return TenantNetwork.State.DOWN;
        } else if ("ERROR".equals(state)) {
            return TenantNetwork.State.ERROR;
        } else {
            return null;
        }
    }

    private Type isType(String type) {
        if ("LOCAL".equals(type)) {
            return TenantNetwork.Type.LOCAL;
        } else {
            return null;
        }
    }

    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response getNetwork(@PathParam("id") String id) {

        if (!get(TenantNetworkService.class).exists(TenantNetworkId
                                                            .networkId(id))) {
            return Response.status(NOT_FOUND)
                    .entity(NETWORK_NOT_FOUND).build();
        }
        TenantNetwork network = nullIsNotFound(get(TenantNetworkService.class)
                .getNetwork(TenantNetworkId.networkId(id)), NETWORK_NOT_FOUND);
        ObjectNode result = new ObjectMapper().createObjectNode();
        result.set("network", new TenantNetworkCodec().encode(network, this));

        return ok(result.toString()).build();

    }

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response createNetworks(InputStream input) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode cfg = readTreeFromStream(mapper, input);
            JsonNode nodes = null;
            Iterable<TenantNetwork> networks = null;
            if (cfg.get("network") != null) {
                nodes = cfg.get("network");
                if (nodes.isArray()) {
                    networks = changeJson2objs(nodes);
                } else {
                    networks = changeJson2obj(CREATE_NETWORK, null, nodes);
                }
            } else if (cfg.get("networks") != null) {
                nodes = cfg.get("networks");
                networks = changeJson2objs(nodes);
            }
            Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)
                                                       .createNetworks(networks)),
                                               NETWORK_NOT_FOUND);

            if (!issuccess) {
                return Response.status(INTERNAL_SERVER_ERROR)
                        .entity(NETWORK_ID_EXIST).build();
            }
            return Response.status(OK).entity(issuccess.toString()).build();
        } catch (Exception e) {
            log.error("Creates tenantNetwork exception {}.", e.toString());
            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
                    .build();
        }
    }

    @PUT
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response updateNetworks(@PathParam("id") String id, InputStream input) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode cfg = readTreeFromStream(mapper, input);
            JsonNode nodes = null;
            Iterable<TenantNetwork> networks = null;
            if (cfg.get("network") != null) {
                nodes = cfg.get("network");
                if (nodes.isArray()) {
                    networks = changeJson2objs(nodes);
                } else {
                    networks = changeJson2obj(UPDATE_NETWORK,
                                              TenantNetworkId.networkId(id),
                                              nodes);
                }
            } else if (cfg.get("networks") != null) {
                nodes = cfg.get("networks");
                networks = changeJson2objs(nodes);
            }
            Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)
                                                       .updateNetworks(networks)),
                                               NETWORK_NOT_FOUND);
            if (!issuccess) {
                return Response.status(INTERNAL_SERVER_ERROR)
                        .entity(NETWORK_ID_NOT_EXIST).build();
            }
            return Response.status(OK).entity(issuccess.toString()).build();
        } catch (Exception e) {
            log.error("Updates tenantNetwork failed because of exception {}.",
                      e.toString());
            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
                    .build();
        }
    }

    @DELETE
    @Path("{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response deleteNetworks(@PathParam("id") String id) {
        log.debug("Deletes network by identifier {}.", id);
        Set<TenantNetworkId> networkSet = new HashSet<>();
        networkSet.add(TenantNetworkId.networkId(id));
        Boolean issuccess = nullIsNotFound(get(TenantNetworkService.class)
                .removeNetworks(networkSet), NETWORK_NOT_FOUND);
        if (!issuccess) {
            log.debug("Network identifier {} is not existed", id);
            return Response.status(INTERNAL_SERVER_ERROR)
                    .entity(NETWORK_ID_NOT_EXIST).build();
        }
        return ok(issuccess.toString()).build();
    }

    /**
     * Returns a collection of tenantNetworks.
     *
     * @param flag the flag
     * @param networkId network identifier
     * @param node the network json node
     * @return a collection of tenantNetworks
     */
    public Iterable<TenantNetwork> changeJson2obj(String flag,
                                                  TenantNetworkId networkId,
                                                  JsonNode node) {
        checkNotNull(node, JSON_NOT_NULL);
        TenantNetwork network = null;
        ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
                .newConcurrentMap();
        checkArgument(node.get("admin_state_up").isBoolean(), "admin_state_up should be boolean");
        checkArgument(node.get("shared").isBoolean(), "shared should be boolean");
        checkArgument(node.get("router:external").isBoolean(), "router:external should be boolean");
        String name = node.get("name").asText();
        boolean adminStateUp = node.get("admin_state_up").asBoolean();
        String state = node.get("status").asText();
        boolean shared = node.get("shared").asBoolean();
        String tenantIdStr = node.get("tenant_id").asText();
        boolean routerExternal = node.get("router:external").asBoolean();
        String type = node.get("provider:network_type").asText();
        String physicalNetwork = node.get("provider:physical_network").asText();
        String segmentationIdStr = node.get("provider:segmentation_id").asText();
        SegmentationId segmentationId = SegmentationId.segmentationId(segmentationIdStr);
        TenantId tenantId = TenantId.tenantId(tenantIdStr);
        if (segmentationIdStr == null || "null".equals(segmentationIdStr)) {
            segmentationId = get(VtnRscService.class).getL3vni(tenantId);
        }
        TenantNetworkId id = null;
        if (flag.equals(CREATE_NETWORK)) {
            id = TenantNetworkId.networkId(node.get("id").asText());
        } else if (flag.equals(UPDATE_NETWORK)) {
            id = networkId;
        }
        network = new DefaultTenantNetwork(
                                           id,
                                           name,
                                           adminStateUp,
                                           isState(state),
                                           shared,
                                           tenantId,
                                           routerExternal,
                                           isType(type),
                                           PhysicalNetwork
                                                   .physicalNetwork(physicalNetwork),
                                           segmentationId);
        networksMap.putIfAbsent(id, network);

        return Collections.unmodifiableCollection(networksMap.values());
    }

    /**
     * Returns a collection of tenantNetworks.
     *
     * @param nodes the network jsonnodes
     * @return a collection of tenantNetworks
     */
    public Iterable<TenantNetwork> changeJson2objs(JsonNode nodes) {
        checkNotNull(nodes, JSON_NOT_NULL);
        TenantNetwork network = null;
        ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
                .newConcurrentMap();
        for (JsonNode node : nodes) {
            String id = node.get("id").asText();
            String name = node.get("name").asText();
            boolean adminStateUp = node.get("admin_state_up").asBoolean();
            String state = node.get("status").asText();
            boolean shared = node.get("shared").asBoolean();
            String tenantIdStr = node.get("tenant_id").asText();
            boolean routerExternal = node.get("router:external")
                    .asBoolean();
            String type = node.get("provider:network_type").asText();
            String physicalNetwork = node.get("provider:physical_network").asText();
            String segmentationIdStr = node.get("provider:segmentation_id").asText();
            SegmentationId segmentationId = SegmentationId.segmentationId(segmentationIdStr);
            TenantId tenantId = TenantId.tenantId(tenantIdStr);
            if (segmentationIdStr == null || "null".equals(segmentationIdStr)) {
                segmentationId = get(VtnRscService.class).getL3vni(tenantId);
            }
            network = new DefaultTenantNetwork(
                                               TenantNetworkId.networkId(id),
                                               name,
                                               adminStateUp,
                                               isState(state),
                                               shared,
                                               tenantId,
                                               routerExternal,
                                               isType(type),
                                               PhysicalNetwork.physicalNetwork(physicalNetwork),
                                               segmentationId);
            networksMap.putIfAbsent(TenantNetworkId.networkId(id), network);
        }

        return Collections.unmodifiableCollection(networksMap.values());
    }

    /**
     * Returns the specified item if that items is null; otherwise throws not
     * found exception.
     *
     * @param item item to check
     * @param <T> item type
     * @param message not found message
     * @return item if not null
     * @throws org.onlab.util.ItemNotFoundException if item is null
     */
    protected <T> T nullIsNotFound(T item, String message) {
        if (item == null) {
            throw new ItemNotFoundException(message);
        }
        return item;
    }
}
