/*
 * 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.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.cluster.RoleInfo;
import org.onosproject.mastership.MastershipAdminService;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.MastershipRole;
import org.onosproject.rest.AbstractWebResource;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
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.IOException;
import java.io.InputStream;
import java.util.Set;

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

/**
 * Manage the mastership of ONOS instances.
 */
@Path("mastership")
public final class MastershipWebResource extends AbstractWebResource {

    private static final String DEVICE_IDS = "deviceIds";
    private static final String DEVICE_ID = "deviceId";
    private static final String NODE_ID = "nodeId";

    private static final String DEVICE_ID_INVALID = "Invalid deviceId for setting role";
    private static final String NODE_ID_INVALID = "Invalid nodeId for setting role";

    private static final String NODE_ID_NOT_FOUND = "Node id is not found";
    private static final String ROLE_INFO_NOT_FOUND = "Role info is not found";
    private static final String MASTERSHIP_ROLE_NOT_FOUND = "Mastership role is not found";

    private final MastershipService mastershipService = get(MastershipService.class);
    private final MastershipAdminService mastershipAdminService =
                                         get(MastershipAdminService.class);

    /**
     * Returns the role of the local node for the specified device.
     *
     * @param deviceId device identifier
     * @return role of the current node
     * @onos.rsModel MastershipRole
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{deviceId}/local")
    public Response getLocalRole(@PathParam("deviceId") String deviceId) {
        MastershipRole role = mastershipService.getLocalRole(DeviceId.deviceId(deviceId));
        ObjectNode root = codec(MastershipRole.class).encode(role, this);
        return ok(root).build();
    }

    /**
     * Returns the current master for a given device.
     *
     * @param deviceId device identifier
     * @return the identifier of the master controller for the device
     * @onos.rsModel NodeId
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{deviceId}/master")
    public Response getMasterFor(@PathParam("deviceId") String deviceId) {
        NodeId id = nullIsNotFound(mastershipService.getMasterFor(
                    DeviceId.deviceId(deviceId)), NODE_ID_NOT_FOUND);

        ObjectNode root = mapper().createObjectNode();
        root.put(NODE_ID, id.id());
        return ok(root).build();
    }

    /**
     * Returns controllers connected to a given device, in order of
     * preference. The first entry in the list is the current master.
     *
     * @param deviceId device identifier
     * @return a list of controller identifiers
     * @onos.rsModel RoleInfo
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{deviceId}/role")
    public Response getNodesFor(@PathParam("deviceId") String deviceId) {
        RoleInfo info = nullIsNotFound(mastershipService.getNodesFor(
                        DeviceId.deviceId(deviceId)), ROLE_INFO_NOT_FOUND);
        ObjectNode root = codec(RoleInfo.class).encode(info, this);
        return ok(root).build();
    }

    /**
     * Returns the devices for which a controller is master.
     *
     * @param nodeId controller identifier
     * @return a set of device identifiers
     * @onos.rsModel DeviceIds
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{nodeId}/device")
    public Response getDeviceOf(@PathParam("nodeId") String nodeId) {
        ObjectNode root = mapper().createObjectNode();
        ArrayNode devicesNode = root.putArray(DEVICE_IDS);

        Set<DeviceId> devices = mastershipService.getDevicesOf(NodeId.nodeId(nodeId));
        if (devices != null) {
            devices.forEach(id -> devicesNode.add(id.toString()));
        }

        return ok(root).build();
    }

    /**
     * Returns the mastership status of the local controller for a given
     * device forcing master selection if necessary.
     *
     * @param deviceId device identifier
     * @return the role of this controller instance
     * @onos.rsModel MastershipRole
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{deviceId}/request")
    public Response requestRoleFor(@PathParam("deviceId") String deviceId) {
        MastershipRole role = nullIsNotFound(mastershipService.requestRoleForSync(
                                DeviceId.deviceId(deviceId)), MASTERSHIP_ROLE_NOT_FOUND);
        ObjectNode root = codec(MastershipRole.class).encode(role, this);
        return ok(root).build();
    }

    /**
     * Abandons mastership of the specified device on the local node thus
     * forcing selection of a new master. If the local node is not a master
     * for this device, no master selection will occur.
     *
     * @param deviceId device identifier
     * @return status of the request
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("{deviceId}/relinquish")
    public Response relinquishMastership(@PathParam("deviceId") String deviceId) {
        DeviceId id = DeviceId.deviceId(deviceId);
        mastershipService.relinquishMastershipSync(id);
        return Response.created(id.uri()).build();
    }

    /**
     * Applies the current mastership role for the specified device.
     *
     * @param stream JSON representation of device, node, mastership info
     * @return status of the request - CREATED if the JSON is correct,
     * BAD_REQUEST if the JSON is invalid
     * @onos.rsModel MastershipPut
     */
    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response setRole(InputStream stream) {

        try {
            ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
            JsonNode deviceIdJson = jsonTree.get(DEVICE_ID);
            JsonNode nodeIdJson = jsonTree.get(NODE_ID);
            MastershipRole role = codec(MastershipRole.class).decode(jsonTree, this);

            if (deviceIdJson == null) {
                throw new IllegalArgumentException(DEVICE_ID_INVALID);
            }

            if (nodeIdJson == null) {
                throw new IllegalArgumentException(NODE_ID_INVALID);
            }

            mastershipAdminService.setRoleSync(NodeId.nodeId(nodeIdJson.asText()),
                    DeviceId.deviceId(deviceIdJson.asText()), role);

            return Response.ok().build();
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Balances the mastership to be shared as evenly as possibly by all
     * online instances.
     *
     * @return status of the request - OK if the request is successfully processed
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response balanceRoles() {
        mastershipAdminService.balanceRoles();
        return Response.ok().build();
    }
}
