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

/**
 * 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";

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

    @GET
    @Produces({ 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 (state.equals("ACTIVE")) {
            return TenantNetwork.State.ACTIVE;
        } else if (state.equals("BUILD")) {
            return TenantNetwork.State.BUILD;
        } else if (state.equals("DOWN")) {
            return TenantNetwork.State.DOWN;
        } else if (state.equals("ERROR")) {
            return TenantNetwork.State.ERROR;
        } else {
            return null;
        }
    }

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

    @GET
    @Path("{id}")
    @Produces({ 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 = mapper.readTree(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 = mapper.readTree(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 tenantId = 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 segmentationId = node.get("provider:segmentation_id").asText();
        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.tenantId(tenantId),
                                           routerExternal,
                                           isType(type),
                                           PhysicalNetwork
                                                   .physicalNetwork(physicalNetwork),
                                           SegmentationId
                                                   .segmentationId(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 tenantId = 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 segmentationId = node.get("provider:segmentation_id").asText();
            network = new DefaultTenantNetwork(
                                               TenantNetworkId.networkId(id),
                                               name,
                                               adminStateUp,
                                               isState(state),
                                               shared,
                                               TenantId.tenantId(tenantId),
                                               routerExternal,
                                               isType(type),
                                               PhysicalNetwork.physicalNetwork(physicalNetwork),
                                               SegmentationId.segmentationId(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;
    }
}
