/*
 * 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.apache.cassandra.tools.nodetool;

import io.airlift.command.Arguments;
import io.airlift.command.Command;
import io.airlift.command.Option;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DecimalFormat;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;

import org.apache.cassandra.locator.EndpointSnitchInfoMBean;
import org.apache.cassandra.tools.NodeProbe;
import org.apache.cassandra.tools.NodeTool;
import org.apache.cassandra.tools.NodeTool.NodeToolCmd;

import com.google.common.collect.ArrayListMultimap;

@Command(name = "status", description = "Print cluster information (state, load, IDs, ...)")
public class Status extends NodeToolCmd
{
    @Arguments(usage = "[<keyspace>]", description = "The keyspace name")
    private String keyspace = null;

    @Option(title = "resolve_ip", name = {"-r", "--resolve-ip"}, description = "Show node domain names instead of IPs")
    private boolean resolveIp = false;

    private boolean isTokenPerNode = true;
    private int maxAddressLength = 0;
    private String format = null;
    private Collection<String> joiningNodes, leavingNodes, movingNodes, liveNodes, unreachableNodes;
    private Map<String, String> loadMap, hostIDMap;
    private EndpointSnitchInfoMBean epSnitchInfo;

    @Override
    public void execute(NodeProbe probe)
    {
        joiningNodes = probe.getJoiningNodes();
        leavingNodes = probe.getLeavingNodes();
        movingNodes = probe.getMovingNodes();
        loadMap = probe.getLoadMap();
        Map<String, String> tokensToEndpoints = probe.getTokenToEndpointMap();
        liveNodes = probe.getLiveNodes();
        unreachableNodes = probe.getUnreachableNodes();
        hostIDMap = probe.getHostIdMap();
        epSnitchInfo = probe.getEndpointSnitchInfoProxy();

        StringBuffer errors = new StringBuffer();

        Map<InetAddress, Float> ownerships = null;
        boolean hasEffectiveOwns = false;
        try
        {
            ownerships = probe.effectiveOwnership(keyspace);
            hasEffectiveOwns = true;
        }
        catch (IllegalStateException e)
        {
            ownerships = probe.getOwnership();
            errors.append("Note: " + e.getMessage() + "%n");
        }
        catch (IllegalArgumentException ex)
        {
            System.out.printf("%nError: %s%n", ex.getMessage());
            System.exit(1);
        }

        SortedMap<String, SetHostStat> dcs = NodeTool.getOwnershipByDc(probe, resolveIp, tokensToEndpoints, ownerships);

        // More tokens than nodes (aka vnodes)?
        if (dcs.values().size() < tokensToEndpoints.keySet().size())
            isTokenPerNode = false;

        findMaxAddressLength(dcs);

        // Datacenters
        for (Map.Entry<String, SetHostStat> dc : dcs.entrySet())
        {
            String dcHeader = String.format("Datacenter: %s%n", dc.getKey());
            System.out.printf(dcHeader);
            for (int i = 0; i < (dcHeader.length() - 1); i++) System.out.print('=');
            System.out.println();

            // Legend
            System.out.println("Status=Up/Down");
            System.out.println("|/ State=Normal/Leaving/Joining/Moving");

            printNodesHeader(hasEffectiveOwns, isTokenPerNode);

            ArrayListMultimap<InetAddress, HostStat> hostToTokens = ArrayListMultimap.create();
            for (HostStat stat : dc.getValue())
                hostToTokens.put(stat.endpoint, stat);

            for (InetAddress endpoint : hostToTokens.keySet())
            {
                Float owns = ownerships.get(endpoint);
                List<HostStat> tokens = hostToTokens.get(endpoint);
                printNode(endpoint.getHostAddress(), owns, tokens, hasEffectiveOwns, isTokenPerNode);
            }
        }

        System.out.printf("%n" + errors.toString());

    }

    private void findMaxAddressLength(Map<String, SetHostStat> dcs)
    {
        maxAddressLength = 0;
        for (Map.Entry<String, SetHostStat> dc : dcs.entrySet())
        {
            for (HostStat stat : dc.getValue())
            {
                maxAddressLength = Math.max(maxAddressLength, stat.ipOrDns().length());
            }
        }
    }

    private void printNodesHeader(boolean hasEffectiveOwns, boolean isTokenPerNode)
    {
        String fmt = getFormat(hasEffectiveOwns, isTokenPerNode);
        String owns = hasEffectiveOwns ? "Owns (effective)" : "Owns";

        if (isTokenPerNode)
            System.out.printf(fmt, "-", "-", "Address", "Load", owns, "Host ID", "Token", "Rack");
        else
            System.out.printf(fmt, "-", "-", "Address", "Load", "Tokens", owns, "Host ID", "Rack");
    }

    private void printNode(String endpoint, Float owns, List<HostStat> tokens, boolean hasEffectiveOwns, boolean isTokenPerNode)
    {
        String status, state, load, strOwns, hostID, rack, fmt;
        fmt = getFormat(hasEffectiveOwns, isTokenPerNode);
        if (liveNodes.contains(endpoint)) status = "U";
        else if (unreachableNodes.contains(endpoint)) status = "D";
        else status = "?";
        if (joiningNodes.contains(endpoint)) state = "J";
        else if (leavingNodes.contains(endpoint)) state = "L";
        else if (movingNodes.contains(endpoint)) state = "M";
        else state = "N";

        load = loadMap.containsKey(endpoint) ? loadMap.get(endpoint) : "?";
        strOwns = owns != null && hasEffectiveOwns ? new DecimalFormat("##0.0%").format(owns) : "?";
        hostID = hostIDMap.get(endpoint);

        try
        {
            rack = epSnitchInfo.getRack(endpoint);
        } catch (UnknownHostException e)
        {
            throw new RuntimeException(e);
        }

        String endpointDns = tokens.get(0).ipOrDns();
        if (isTokenPerNode)
            System.out.printf(fmt, status, state, endpointDns, load, strOwns, hostID, tokens.get(0).token, rack);
        else
            System.out.printf(fmt, status, state, endpointDns, load, tokens.size(), strOwns, hostID, rack);
    }

    private String getFormat(
            boolean hasEffectiveOwns,
            boolean isTokenPerNode)
    {
        if (format == null)
        {
            StringBuilder buf = new StringBuilder();
            String addressPlaceholder = String.format("%%-%ds  ", maxAddressLength);
            buf.append("%s%s  ");                         // status
            buf.append(addressPlaceholder);               // address
            buf.append("%-9s  ");                         // load
            if (!isTokenPerNode)
                buf.append("%-11s  ");                     // "Tokens"
            if (hasEffectiveOwns)
                buf.append("%-16s  ");                    // "Owns (effective)"
            else
                buf.append("%-6s  ");                     // "Owns
            buf.append("%-36s  ");                        // Host ID
            if (isTokenPerNode)
                buf.append("%-39s  ");                    // token
            buf.append("%s%n");                           // "Rack"

            format = buf.toString();
        }

        return format;
    }
}
