/*
 * Copyright 2016 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.util.ItemNotFoundException;
import org.onosproject.incubator.net.virtual.TenantId;
import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
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;

/**
 * Query and manage tenants of virtual networks.
 */
@Path("tenants")
public class TenantWebResource extends AbstractWebResource {

    private static final String MISSING_TENANTID = "Missing tenant identifier";
    private static final String TENANTID_NOT_FOUND = "Tenant identifier not found";
    private static final String INVALID_TENANTID = "Invalid tenant identifier ";

    @Context
    UriInfo uriInfo;

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

    /**
     * Returns all tenants.
     *
     * @return 200 OK
     * @onos.rsModel TenantIds
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getVirtualNetworkTenants() {
        Iterable<TenantId> tenantIds = vnetAdminService.getTenantIds();
        return ok(encodeArray(TenantId.class, "tenants", tenantIds)).build();
    }

    /**
     * Creates a tenant with the given tenant identifier.
     *
     * @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 addTenantId(InputStream stream) {
        try {
            final TenantId tid = getTenantIdFromJsonStream(stream);
            vnetAdminService.registerTenantId(tid);
            final TenantId resultTid = getExistingTenantId(vnetAdminService, tid);
            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
                    .path("tenants")
                    .path(resultTid.id());
            return Response
                    .created(locationBuilder.build())
                    .build();
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Removes the specified tenant with the specified tenant identifier.
     *
     * @param tenantId tenant identifier
     * @return 200 OK, 404 not found
     */
    @DELETE
    @Path("{tenantId}")
    public Response removeTenantId(@PathParam("tenantId") String tenantId) {
        final TenantId tid = TenantId.tenantId(tenantId);
        final TenantId existingTid = getExistingTenantId(vnetAdminService, tid);
        vnetAdminService.unregisterTenantId(existingTid);
        return Response.ok().build();
    }

    /**
     * Removes the specified tenant with the specified tenant identifier.
     *
     * @param stream deviceIds JSON stream
     * @return 200 OK, 404 not found
     * @onos.rsModel TenantId
     */
    @DELETE
    public Response removeTenantId(InputStream stream) {
        try {
            final TenantId tid = getTenantIdFromJsonStream(stream);
            vnetAdminService.unregisterTenantId(tid);
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
        return Response.ok().build();
    }

    /**
     * Get the tenant identifier from the JSON stream.
     *
     * @param stream TenantId JSON stream
     * @return TenantId
     * @throws IOException
     */
    private TenantId getTenantIdFromJsonStream(InputStream stream) throws IOException {
        ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
        JsonNode specifiedTenantId = jsonTree.get("id");

        if (specifiedTenantId == null) {
            throw new IllegalArgumentException(MISSING_TENANTID);
        }
        return TenantId.tenantId(specifiedTenantId.asText());
    }

    /**
     * Get the matching tenant identifier from existing tenant identifiers in system.
     *
     * @param vnetAdminSvc
     * @param tidIn tenant identifier
     * @return TenantId
     */
    private static TenantId getExistingTenantId(VirtualNetworkAdminService vnetAdminSvc,
                                               TenantId tidIn) {
        final TenantId resultTid = vnetAdminSvc
                .getTenantIds()
                .stream()
                .filter(tenantId -> tenantId.equals(tidIn))
                .findFirst()
                .orElseThrow(() -> new ItemNotFoundException(TENANTID_NOT_FOUND));
        return resultTid;
    }
}
