/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.onlab.onos.cli;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cluster.NodeId;
import org.onlab.onos.cluster.RoleInfo;
import org.onlab.onos.mastership.MastershipService;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.device.DeviceService;

import java.util.List;

import static org.onlab.onos.cli.net.DevicesListCommand.getSortedDevices;

/**
 * Lists mastership roles of nodes for each device.
 */
@Command(scope = "onos", name = "roles",
         description = "Lists mastership roles of nodes for each device.")
public class RolesCommand extends AbstractShellCommand {

    private static final String FMT_HDR = "%s: master=%s, standbys=[ %s]";

    @Override
    protected void execute() {
        DeviceService deviceService = get(DeviceService.class);
        MastershipService roleService = get(MastershipService.class);

        if (outputJson()) {
            print("%s", json(roleService, getSortedDevices(deviceService)));
        } else {
            for (Device d : getSortedDevices(deviceService)) {
                DeviceId did = d.id();
                printRoles(roleService, did);
            }
        }
    }

    // Produces JSON structure with role information for the given devices.
    private JsonNode json(MastershipService service, List<Device> sortedDevices) {
        ObjectMapper mapper = new ObjectMapper();
        ArrayNode results = mapper.createArrayNode();
        for (Device device : sortedDevices) {
            results.add(json(service, mapper, device));
        }
        return results;
    }

    // Produces JSON structure with role information for the given device.
    private JsonNode json(MastershipService service, ObjectMapper mapper,
                          Device device) {
        NodeId master = service.getMasterFor(device.id());
        ObjectNode result = mapper.createObjectNode()
                .put("id", device.id().toString())
                .put("master", master != null ? master.toString() : "none");
        RoleInfo nodes = service.getNodesFor(device.id());
        ArrayNode standbys = mapper.createArrayNode();
        for (NodeId nid : nodes.backups()) {
            standbys.add(nid.toString());
        }
        result.set("standbys", standbys);
        return result;
    }

    /**
     * Prints the role information for a device.
     *
     * @param service  mastership service
     * @param deviceId the ID of the device
     */
    protected void printRoles(MastershipService service, DeviceId deviceId) {
        RoleInfo nodes = service.getNodesFor(deviceId);
        StringBuilder builder = new StringBuilder();
        for (NodeId nid : nodes.backups()) {
            builder.append(nid).append(" ");
        }

        print(FMT_HDR, deviceId,
              nodes.master() == null ? "NONE" : nodes.master(),
              builder.toString());
    }
}
