/*
 * Copyright 2018-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.incubator.net.virtual.rest;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.util.ItemNotFoundException;
import org.onosproject.net.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;

import static org.onlab.util.Tools.readTreeFromStream;

/**
 * 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
    private UriInfo uriInfo;

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

    /**
     * Returns all tenant identifiers.
     *
     * @return 200 OK with set of tenant identifiers
     * @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();
    }

    /**
     * Gets 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 = readTreeFromStream(mapper(), 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
     */
    protected static TenantId getExistingTenantId(VirtualNetworkAdminService vnetAdminSvc,
                                                TenantId tidIn) {
        return vnetAdminSvc
                .getTenantIds()
                .stream()
                .filter(tenantId -> tenantId.equals(tidIn))
                .findFirst()
                .orElseThrow(() -> new ItemNotFoundException(TENANTID_NOT_FOUND));
    }
}
