/*
 * 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.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 getVirtualNetworkTenantIds() {
        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 204 NO CONTENT
     */
    @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.noContent().build();
    }

    /**
     * Get the tenant identifier from the JSON stream.
     *
     * @param stream TenantId JSON stream
     * @return TenantId
     * @throws IOException if unable to parse the request
     */
    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 virtual network administration service
     * @param tidIn tenant identifier
     * @return TenantId
     */
     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;
    }
}
