/*
 * Copyright 2014-2015 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.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.host.DefaultHostDescription;
import org.onosproject.net.host.HostProvider;
import org.onosproject.net.host.HostProviderRegistry;
import org.onosproject.net.host.HostProviderService;
import org.onosproject.net.host.HostService;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.rest.AbstractWebResource;

import javax.ws.rs.Consumes;
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.net.URI;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import static org.onlab.util.Tools.nullIsNotFound;
import static org.onosproject.net.HostId.hostId;

/**
 * REST resource for interacting with the inventory of hosts.
 */
@Path("hosts")
public class HostsWebResource extends AbstractWebResource {

    @Context
    UriInfo uriInfo;
    public static final String HOST_NOT_FOUND = "Host is not found";

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getHosts() {
        final Iterable<Host> hosts = get(HostService.class).getHosts();
        final ObjectNode root = encodeArray(Host.class, "hosts", hosts);
        return ok(root).build();
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{id}")
    public Response getHostById(@PathParam("id") String id) {
        final Host host = nullIsNotFound(get(HostService.class).getHost(hostId(id)),
                                         HOST_NOT_FOUND);
        final ObjectNode root = codec(Host.class).encode(host, this);
        return ok(root).build();
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{mac}/{vlan}")
    public Response getHostByMacAndVlan(@PathParam("mac") String mac,
                                        @PathParam("vlan") String vlan) {
        final Host host = nullIsNotFound(get(HostService.class).getHost(hostId(mac + "/" + vlan)),
                                         HOST_NOT_FOUND);
        final ObjectNode root = codec(Host.class).encode(host, this);
        return ok(root).build();
    }

    /**
     * Creates a new host based on JSON input and adds it to the current
     * host inventory.
     *
     * @param stream input JSON
     * @return status of the request - CREATED if the JSON is correct,
     * BAD_REQUEST if the JSON is invalid
     */
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createAndAddHost(InputStream stream) {
        URI location;
        try {
            // Parse the input stream
            ObjectNode root = (ObjectNode) mapper().readTree(stream);

            HostProviderRegistry hostProviderRegistry = get(HostProviderRegistry.class);
            InternalHostProvider hostProvider = new InternalHostProvider(hostProviderRegistry);
            hostProvider.register();
            HostId hostId = hostProvider.parseHost(root);

            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
                    .path("hosts")
                    .path(hostId.mac().toString())
                    .path(hostId.vlanId().toString());
            location = locationBuilder.build();
            hostProvider.unregister();

        } catch (IOException ex) {
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
        }
        return Response
                .created(location)
                .build();
    }

    /**
     * Produces annotations from specified JsonNode. Copied from the ConfigProvider
     * class for use in the POST method.
     *
     * @param node node to be annotated
     * @return SparseAnnotations object with information about node
     */
    private SparseAnnotations annotations(JsonNode node) {
        if (node == null) {
            return DefaultAnnotations.EMPTY;
        }

        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
        Iterator<String> it = node.fieldNames();
        while (it.hasNext()) {
            String k = it.next();
            builder.set(k, node.get(k).asText());
        }
        return builder.build();
    }

    private final class InternalHostProvider implements HostProvider {
        private final ProviderId providerId =
                new ProviderId("host", "org.onosproject.rest", true);
        private HostProviderRegistry hostProviderRegistry;
        private HostProviderService hostProviderService;

        public void triggerProbe(Host host) {
            // No need to implement since we don't need to check if the host exists
        }

        private InternalHostProvider(HostProviderRegistry hostProviderRegistry) {
            this.hostProviderRegistry = hostProviderRegistry;
        }

        private void register() {
            this.hostProviderService = hostProviderRegistry.register(this);
        }

        private void unregister() {
            hostProviderRegistry.unregister(this);
        }

        public ProviderId id() {
            return providerId;
        }

        /**
         * Creates and adds new host based on given data and returns its host ID.
         * @param node JsonNode containing host information
         * @return host ID of new host created
         */
        private HostId parseHost(JsonNode node) {
            MacAddress mac = MacAddress.valueOf(node.get("mac").asText());
            VlanId vlanId = VlanId.vlanId(((short) node.get("vlan").asInt((VlanId.UNTAGGED))));
            JsonNode locationNode = node.get("location");
            String deviceAndPort = locationNode.get("elementId").asText() + "/" +
                    locationNode.get("port").asText();
            HostLocation hostLocation = new HostLocation(ConnectPoint.deviceConnectPoint(deviceAndPort), 0);

            Iterator<JsonNode> ipStrings = node.get("ipAddresses").elements();
            Set<IpAddress> ips = new HashSet<>();
            while (ipStrings.hasNext()) {
                ips.add(IpAddress.valueOf(ipStrings.next().asText()));
            }
            SparseAnnotations annotations = annotations(node);
            // Update host inventory

            HostId hostId = HostId.hostId(mac, vlanId);
            DefaultHostDescription desc = new DefaultHostDescription(mac, vlanId, hostLocation, ips, annotations);
            hostProviderService.hostDetected(hostId, desc);
            return hostId;
        }
    }
}

