/*
 * 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.openstacknetworking.web;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.openstackinterface.OpenstackFloatingIP;
import org.onosproject.openstackinterface.web.OpenstackFloatingIpCodec;
import org.onosproject.openstacknetworking.api.OpenstackFloatingIpService;
import org.onosproject.rest.AbstractWebResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
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.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Handles REST API call of Neutron L3 plugin.
 */
@Path("floatingips")
public class OpenstackFloatingIpWebResource extends AbstractWebResource {
    private final Logger log = LoggerFactory.getLogger(getClass());

    private static final OpenstackFloatingIpCodec FLOATING_IP_CODEC = new OpenstackFloatingIpCodec();

    /**
     * Create FloatingIP.
     *
     * @param input JSON data describing FloatingIP
     * @return 200 OK
     */
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createFloatingIp(InputStream input) {
        checkNotNull(input);

        try {
            ObjectMapper mapper = new ObjectMapper();
            ObjectNode floatingIpNode = (ObjectNode) mapper.readTree(input);

            OpenstackFloatingIP osFloatingIp = FLOATING_IP_CODEC.decode(floatingIpNode, this);
            OpenstackFloatingIpService floatingIpService =
                    getService(OpenstackFloatingIpService.class);
            floatingIpService.createFloatingIp(osFloatingIp);

            log.debug("REST API CREATE floatingip called");
            return Response.status(Response.Status.OK).build();
        } catch (Exception e) {
            log.error("createFloatingIp failed with {}", e.toString());
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString())
                    .build();
        }
    }

    /**
     * Update FloatingIP.
     *
     * @param id    FloatingIP identifier
     * @param input JSON data describing FloatingIP
     * @return 200 OK
     */
    @PUT
    @Path("{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response updateFloatingIp(@PathParam("id") String id, InputStream input) {
        checkNotNull(id);
        checkNotNull(input);

        try {
            ObjectMapper mapper = new ObjectMapper();
            ObjectNode floatingIpNode = (ObjectNode) mapper.readTree(input);

            OpenstackFloatingIP osFloatingIp = FLOATING_IP_CODEC.decode(floatingIpNode, this);
            OpenstackFloatingIpService floatingIpService =
                    getService(OpenstackFloatingIpService.class);
            floatingIpService.updateFloatingIp(osFloatingIp);

            log.debug("REST API UPDATE floatingip called {}", id);
            return Response.status(Response.Status.OK).build();
        } catch (Exception e) {
            log.error("updateFloatingIp failed with {}", e.toString());
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString())
                    .build();
        }
    }

    /**
     * Delete FloatingIP.
     *
     * @param id FloatingIP identifier
     * @return 204 OK
     */
    @DELETE
    @Path("{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response deleteFloatingIp(@PathParam("id") String id) {
        checkNotNull(id);

        OpenstackFloatingIpService floatingIpService =
                getService(OpenstackFloatingIpService.class);
        floatingIpService.deleteFloatingIp(id);

        log.debug("REST API DELETE floatingip is called {}", id);
        return Response.noContent().build();
    }

}
