/*
 * Copyright 2016-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.rest.resources;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.incubator.net.virtual.NetworkId;
import org.onosproject.incubator.net.virtual.TenantId;
import org.onosproject.incubator.net.virtual.VirtualDevice;
import org.onosproject.incubator.net.virtual.VirtualLink;
import org.onosproject.incubator.net.virtual.VirtualNetwork;
import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
import org.onosproject.incubator.net.virtual.VirtualNetworkService;
import org.onosproject.incubator.net.virtual.VirtualPort;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.rest.AbstractWebResource;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Query and Manage Virtual Network elements.
 */
@Path("vnets")
public class VirtualNetworkWebResource extends AbstractWebResource {

    private static final String MISSING_FIELD = "Missing ";
    private static final String INVALID_FIELD = "Invalid ";

    private final VirtualNetworkAdminService vnetAdminService = get(VirtualNetworkAdminService.class);
    private final VirtualNetworkService vnetService = get(VirtualNetworkService.class);

    @Context
    UriInfo uriInfo;

    // VirtualNetwork

    /**
     * Returns all virtual networks.
     *
     * @return 200 OK
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getVirtualNetworks() {
        Set<TenantId> tenantIds = vnetAdminService.getTenantIds();
        List<VirtualNetwork> allVnets = tenantIds.stream()
                .map(tenantId -> vnetService.getVirtualNetworks(tenantId))
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
        return ok(encodeArray(VirtualNetwork.class, "vnets", allVnets)).build();
    }

    /**
     * Returns the virtual networks with the specified tenant identifier.
     *
     * @param tenantId tenant identifier
     * @return 200 OK, 404 not found
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{tenantId}")
    public Response getVirtualNetworkById(@PathParam("tenantId") String tenantId) {
        final TenantId existingTid = TenantWebResource.getExistingTenantId(vnetAdminService,
                                                                           TenantId.tenantId(tenantId));
        Set<VirtualNetwork> vnets = vnetService.getVirtualNetworks(existingTid);
        return ok(encodeArray(VirtualNetwork.class, "vnets", vnets)).build();
    }

    /**
     * Creates a virtual network from the JSON input stream.
     *
     * @param stream TenantId JSON stream
     * @return status of the request - CREATED if the JSON is correct,
     * BAD_REQUEST if the JSON is invalid
     * @onos.rsModel TenantId
     */
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createVirtualNetwork(InputStream stream) {
        try {
            final TenantId tid = TenantId.tenantId(getFromJsonStream(stream, "id").asText());
            VirtualNetwork newVnet = vnetAdminService.createVirtualNetwork(tid);
            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
                    .path("vnets")
                    .path(newVnet.id().toString());
            return Response
                    .created(locationBuilder.build())
                    .build();
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Removes the virtual network with the specified network identifier.
     *
     * @param networkId network identifier
     * @return 200 OK, 404 not found
     */
    @DELETE
    @Path("{networkId}")
    public Response removeVirtualNetwork(@PathParam("networkId") long networkId) {
        NetworkId nid = NetworkId.networkId(networkId);
        vnetAdminService.removeVirtualNetwork(nid);
        return Response.ok().build();
    }

    // VirtualDevice

    /**
     * Returns all virtual network devices in a virtual network.
     *
     * @param networkId network identifier
     * @return 200 OK
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{networkId}/devices")
    public Response getVirtualDevices(@PathParam("networkId") long networkId) {
        NetworkId nid = NetworkId.networkId(networkId);
        Set<VirtualDevice> vdevs = vnetService.getVirtualDevices(nid);
        return ok(encodeArray(VirtualDevice.class, "devices", vdevs)).build();
    }

    /**
     * Creates a virtual device from the JSON input stream.
     *
     * @param networkId network identifier
     * @param stream    Virtual device JSON stream
     * @return status of the request - CREATED if the JSON is correct,
     * BAD_REQUEST if the JSON is invalid
     * @onos.rsModel VirtualDevice
     */
    @POST
    @Path("{networkId}/devices")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createVirtualDevice(@PathParam("networkId") long networkId,
                                        InputStream stream) {
        try {
            ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
            final VirtualDevice vdevReq = codec(VirtualDevice.class).decode(jsonTree, this);
            JsonNode specifiedNetworkId = jsonTree.get("networkId");
            if (specifiedNetworkId == null || specifiedNetworkId.asLong() != (networkId)) {
                throw new IllegalArgumentException(INVALID_FIELD + "networkId");
            }
            final VirtualDevice vdevRes = vnetAdminService.createVirtualDevice(vdevReq.networkId(),
                                                                               vdevReq.id());
            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
                    .path("vnets").path(specifiedNetworkId.asText())
                    .path("devices").path(vdevRes.id().toString());
            return Response
                    .created(locationBuilder.build())
                    .build();
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Removes the virtual network device from the virtual network.
     *
     * @param networkId network identifier
     * @param deviceId  device identifier
     * @return 200 OK, 404 not found
     */
    @DELETE
    @Path("{networkId}/devices/{deviceId}")
    public Response removeVirtualDevice(@PathParam("networkId") long networkId,
                                        @PathParam("deviceId") String deviceId) {
        NetworkId nid = NetworkId.networkId(networkId);
        DeviceId did = DeviceId.deviceId(deviceId);
        vnetAdminService.removeVirtualDevice(nid, did);
        return Response.ok().build();
    }

    // VirtualPort

    /**
     * Returns all virtual network ports in a virtual device in a virtual network.
     *
     * @param networkId network identifier
     * @param deviceId  virtual device identifier
     * @return 200 OK
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{networkId}/devices/{deviceId}/ports")
    public Response getVirtualPorts(@PathParam("networkId") long networkId,
                                    @PathParam("deviceId") String deviceId) {
        NetworkId nid = NetworkId.networkId(networkId);
        Iterable<VirtualPort> vports = vnetService.getVirtualPorts(nid, DeviceId.deviceId(deviceId));
        return ok(encodeArray(VirtualPort.class, "ports", vports)).build();
    }

    /**
     * Creates a virtual network port in a virtual device in a virtual network.
     *
     * @param networkId    network identifier
     * @param virtDeviceId virtual device identifier
     * @param stream       Virtual device JSON stream
     * @return status of the request - CREATED if the JSON is correct,
     * BAD_REQUEST if the JSON is invalid
     * @onos.rsModel VirtualPort
     */
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{networkId}/devices/{deviceId}/ports")
    public Response createVirtualPort(@PathParam("networkId") long networkId,
                                      @PathParam("deviceId") String virtDeviceId,
                                      InputStream stream) {
        try {
            ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
//            final VirtualPort vportReq = codec(VirtualPort.class).decode(jsonTree, this);
            JsonNode specifiedNetworkId = jsonTree.get("networkId");
            JsonNode specifiedDeviceId = jsonTree.get("deviceId");
            if (specifiedNetworkId == null || specifiedNetworkId.asLong() != (networkId)) {
                throw new IllegalArgumentException(INVALID_FIELD + "networkId");
            }
            if (specifiedDeviceId == null || !specifiedDeviceId.asText().equals(virtDeviceId)) {
                throw new IllegalArgumentException(INVALID_FIELD + "deviceId");
            }
            JsonNode specifiedPortNum = jsonTree.get("portNum");
            JsonNode specifiedPhysDeviceId = jsonTree.get("physDeviceId");
            JsonNode specifiedPhysPortNum = jsonTree.get("physPortNum");
            final NetworkId nid = NetworkId.networkId(networkId);
            DeviceId vdevId = DeviceId.deviceId(virtDeviceId);
            DefaultAnnotations annotations = DefaultAnnotations.builder().build();
            Device physDevice = new DefaultDevice(null, DeviceId.deviceId(specifiedPhysDeviceId.asText()),
                                                  null, null, null, null, null, null, annotations);
            Port realizedBy = new DefaultPort(physDevice,
                                              PortNumber.portNumber(specifiedPhysPortNum.asText()), true);
            VirtualPort vport = vnetAdminService.createVirtualPort(nid, vdevId,
                                    PortNumber.portNumber(specifiedPortNum.asText()), realizedBy);
            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
                    .path("vnets").path(specifiedNetworkId.asText())
                    .path("devices").path(specifiedDeviceId.asText())
                    .path("ports").path(vport.number().toString());
            return Response
                    .created(locationBuilder.build())
                    .build();
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Removes the virtual network port from the virtual device in a virtual network.
     *
     * @param networkId network identifier
     * @param deviceId  virtual device identifier
     * @param portNum   virtual port number
     * @return 200 OK, 404 not found
     */
    @DELETE
    @Path("{networkId}/devices/{deviceId}/ports/{portNum}")
    public Response removeVirtualPort(@PathParam("networkId") long networkId,
                                      @PathParam("deviceId") String deviceId,
                                      @PathParam("portNum") long portNum) {
        NetworkId nid = NetworkId.networkId(networkId);
        vnetAdminService.removeVirtualPort(nid, DeviceId.deviceId(deviceId),
                                           PortNumber.portNumber(portNum));
        return Response.ok().build();
    }

    // VirtualLink

    /**
     * Returns all virtual network links in a virtual network.
     *
     * @param networkId network identifier
     * @return 200 OK
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{networkId}/links")
    public Response getVirtualLinks(@PathParam("networkId") long networkId) {
        NetworkId nid = NetworkId.networkId(networkId);
        Set<VirtualLink> vlinks = vnetService.getVirtualLinks(nid);
        return ok(encodeArray(VirtualLink.class, "links", vlinks)).build();
    }

    /**
     * Creates a virtual network link from the JSON input stream.
     *
     * @param networkId network identifier
     * @param stream    Virtual device JSON stream
     * @return status of the request - CREATED if the JSON is correct,
     * BAD_REQUEST if the JSON is invalid
     * @onos.rsModel VirtualLink
     */
    @POST
    @Path("{networkId}/links")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createVirtualLink(@PathParam("networkId") long networkId,
                                      InputStream stream) {
        try {
            ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
            JsonNode specifiedNetworkId = jsonTree.get("networkId");
            if (specifiedNetworkId == null || specifiedNetworkId.asLong() != (networkId)) {
                throw new IllegalArgumentException(INVALID_FIELD + "networkId");
            }
            final VirtualLink vlinkReq = codec(VirtualLink.class).decode(jsonTree, this);
            vnetAdminService.createVirtualLink(vlinkReq.networkId(),
                                               vlinkReq.src(), vlinkReq.dst());
            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
                    .path("vnets").path(specifiedNetworkId.asText())
                    .path("links");
            return Response
                    .created(locationBuilder.build())
                    .build();
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Removes the virtual network link from the JSON input stream.
     *
     * @param networkId network identifier
     * @param stream    deviceIds JSON stream
     * @return 200 OK, 404 not found
     * @onos.rsModel VirtualLink
     */
    @DELETE
    @Path("{networkId}/links")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response removeVirtualLink(@PathParam("networkId") long networkId,
                                      InputStream stream) {
        try {
            ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
            JsonNode specifiedNetworkId = jsonTree.get("networkId");
            if (specifiedNetworkId != null &&
                    specifiedNetworkId.asLong() != (networkId)) {
                throw new IllegalArgumentException(INVALID_FIELD + "networkId");
            }
            final VirtualLink vlinkReq = codec(VirtualLink.class).decode(jsonTree, this);
            vnetAdminService.removeVirtualLink(vlinkReq.networkId(),
                                               vlinkReq.src(), vlinkReq.dst());
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }

        return Response.ok().build();
    }

    /**
     * Get the tenant identifier from the JSON stream.
     *
     * @param stream        TenantId JSON stream
     * @param jsonFieldName field name
     * @return JsonNode
     * @throws IOException if unable to parse the request
     */
    private JsonNode getFromJsonStream(InputStream stream, String jsonFieldName) throws IOException {
        ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
        JsonNode jsonNode = jsonTree.get(jsonFieldName);

        if (jsonNode == null) {
            throw new IllegalArgumentException(MISSING_FIELD + jsonFieldName);
        }
        return jsonNode;
    }
}
