/*
 * 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.VirtualHost;
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
    private UriInfo uriInfo;

    // VirtualNetwork

    /**
     * Returns all virtual networks.
     *
     * @return 200 OK with set of virtual networks
     * @onos.rsModel VirtualNetworks
     */
    @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 with a virtual network, 404 not found
     * @onos.rsModel VirtualNetworks
     */
    @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 tenant identifier 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 204 NO CONTENT
     */
    @DELETE
    @Path("{networkId}")
    public Response removeVirtualNetwork(@PathParam("networkId") long networkId) {
        NetworkId nid = NetworkId.networkId(networkId);
        vnetAdminService.removeVirtualNetwork(nid);
        return Response.noContent().build();
    }

    // VirtualDevice

    /**
     * Returns all virtual network devices in a virtual network.
     *
     * @param networkId network identifier
     * @return 200 OK with set of virtual devices, 404 not found
     * @onos.rsModel VirtualDevices
     */
    @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 204 NO CONTENT
     */
    @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.noContent().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 with set of virtual ports, 404 not found
     * @onos.rsModel VirtualPorts
     */
    @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 port 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 204 NO CONTENT
     */
    @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.noContent().build();
    }

    // VirtualLink

    /**
     * Returns all virtual network links in a virtual network.
     *
     * @param networkId network identifier
     * @return 200 OK with set of virtual network links
     * @onos.rsModel VirtualLinks
     */
    @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 link 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    virtual link JSON stream
     * @return 204 NO CONTENT
     * @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.noContent().build();
    }

    /**
     * Returns all virtual network hosts in a virtual network.
     *
     * @param networkId network identifier
     * @return 200 OK with set of virtual network hosts
     * @onos.rsModel VirtualHosts
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{networkId}/hosts")
    public Response getVirtualHosts(@PathParam("networkId") long networkId) {
        NetworkId nid = NetworkId.networkId(networkId);
        Set<VirtualHost> vhosts = vnetService.getVirtualHosts(nid);
        return ok(encodeArray(VirtualHost.class, "hosts", vhosts)).build();
    }

    /**
     * Creates a virtual network host from the JSON input stream.
     *
     * @param networkId network identifier
     * @param stream    virtual host JSON stream
     * @return status of the request - CREATED if the JSON is correct,
     * BAD_REQUEST if the JSON is invalid
     * @onos.rsModel VirtualHostPut
     */
    @POST
    @Path("{networkId}/hosts")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createVirtualHost(@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 VirtualHost vhostReq = codec(VirtualHost.class).decode(jsonTree, this);
            vnetAdminService.createVirtualHost(vhostReq.networkId(), vhostReq.id(),
                                               vhostReq.mac(), vhostReq.vlan(),
                                               vhostReq.location(), vhostReq.ipAddresses());
            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
                    .path("vnets").path(specifiedNetworkId.asText())
                    .path("hosts");
            return Response
                    .created(locationBuilder.build())
                    .build();
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Removes the virtual network host from the JSON input stream.
     *
     * @param networkId network identifier
     * @param stream    virtual host JSON stream
     * @return 204 NO CONTENT
     * @onos.rsModel VirtualHost
     */
    @DELETE
    @Path("{networkId}/hosts")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response removeVirtualHost(@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 VirtualHost vhostReq = codec(VirtualHost.class).decode(jsonTree, this);
            vnetAdminService.removeVirtualHost(vhostReq.networkId(), vhostReq.id());
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }

        return Response.noContent().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;
    }
}
