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

    protected 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;
    }
}
