/*
 * 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.dhcp.rest;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress;
import org.onosproject.dhcp.DhcpService;
import org.onosproject.dhcp.IpAssignment;
import org.onosproject.net.HostId;
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.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Map;

import static org.onlab.util.Tools.readTreeFromStream;
import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_Requested;

/**
 * Manage DHCP address assignments.
 */
@Path("dhcp")
public class DhcpWebResource extends AbstractWebResource {

    private final DhcpService service = get(DhcpService.class);

    /**
     * Get DHCP server configuration data.
     * Shows lease, renewal and rebinding times in seconds.
     *
     * @return 200 OK
     * @onos.rsModel DhcpConfigGet
     */
    @GET
    @Path("config")
    public Response getConfigs() {
        ObjectNode node = mapper().createObjectNode()
                .put("leaseTime", service.getLeaseTime())
                .put("renewalTime", service.getRenewalTime())
                .put("rebindingTime", service.getRebindingTime());
        return ok(node).build();
    }

    /**
     * Get all MAC/IP mappings.
     * Shows all MAC/IP mappings held by the DHCP server.
     *
     * @onos.rsModel DhcpConfigGetMappings
     * @return 200 OK
     */
    @GET
    @Path("mappings")
    public Response listMappings() {
        ObjectNode root = mapper().createObjectNode();

        Map<HostId, IpAssignment> intents = service.listMapping();
        ArrayNode arrayNode = root.putArray("mappings");
        intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode()
                                                              .put("host", i.getKey().toString())
                                                              .put("ip", i.getValue().ipAddress().toString())));

        return ok(root).build();
    }


    /**
     * Get all available IPs.
     * Shows all the IPs in the free pool of the DHCP Server.
     *
     * @onos.rsModel DhcpConfigGetAvailable
     * @return 200 OK
     */
    @GET
    @Path("available")
    public Response listAvailableIPs() {
        Iterable<Ip4Address> availableIPList = service.getAvailableIPs();
        ObjectNode root = mapper().createObjectNode();
        ArrayNode arrayNode = root.putArray("availableIP");
        availableIPList.forEach(i -> arrayNode.add(i.toString()));
        return ok(root).build();
    }

    /**
     * Post a new static MAC/IP binding.
     * Registers a static binding to the DHCP server, and displays the current set of bindings.
     *
     * @onos.rsModel DhcpConfigPut
     * @param stream JSON stream
     * @return 200 OK
     */
    @POST
    @Path("mappings")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response setMapping(InputStream stream) {
        ObjectNode root = mapper().createObjectNode();
        try {
            ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
            JsonNode macID = jsonTree.get("mac");
            JsonNode ip = jsonTree.get("ip");
            if (macID != null && ip != null) {
                IpAssignment ipAssignment = IpAssignment.builder()
                        .ipAddress(Ip4Address.valueOf(ip.asText()))
                        .leasePeriod(service.getLeaseTime())
                        .timestamp(new Date())
                        .assignmentStatus(Option_Requested)
                        .build();

                if (!service.setStaticMapping(MacAddress.valueOf(macID.asText()),
                                              ipAssignment)) {
                    throw new IllegalArgumentException("Static Mapping Failed. " +
                                                               "The IP maybe unavailable.");
                }
            }

            final Map<HostId, IpAssignment> intents = service.listMapping();
            ArrayNode arrayNode = root.putArray("mappings");
            intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode()
                                                                  .put("host", i.getKey().toString())
                                                                  .put("ip", i.getValue().ipAddress().toString())));
        } catch (IOException e) {
            throw new IllegalArgumentException(e.getMessage());
        }
        return ok(root).build();
    }

    /**
     * Delete a static MAC/IP binding.
     * Removes a static binding from the DHCP Server, and displays the current set of bindings.
     *
     * @param macID mac address identifier
     * @return 200 OK
     */
    @DELETE
    @Path("mappings/{macID}")
    public Response deleteMapping(@PathParam("macID") String macID) {
        ObjectNode root = mapper().createObjectNode();

        if (!service.removeStaticMapping(MacAddress.valueOf(macID))) {
            throw new IllegalArgumentException("Static Mapping Removal Failed.");
        }
        final Map<HostId, IpAssignment> intents = service.listMapping();
        ArrayNode arrayNode = root.putArray("mappings");
        intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode()
                                                              .put("host", i.getKey().toString())
                                                              .put("ip", i.getValue().ipAddress().toString())));

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