/*
 * Copyright 2014-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.cli.net;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
import org.onlab.util.Tools;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cluster.Leadership;
import org.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;

/**
 * Prints the leader for every topic.
 */
@Command(scope = "onos", name = "leaders",
        description = "Finds the leader for particular topic.")
public class LeaderCommand extends AbstractShellCommand {

    private static final String FMT = "%-30s | %-15s | %-5s | %-10s |";
    private static final String FMT_C = "%-30s | %-15s | %-5s | %-10s | %-19s |";
    private boolean allTopics;
    private Pattern pattern;

    @Argument(index = 0, name = "topic", description = "A leadership topic. Can be a regex",
            required = false, multiValued = false)
    String topicPattern = null;

    @Option(name = "-c", aliases = "--candidates",
            description = "List candidate Nodes for each topic's leadership race",
            required = false, multiValued = false)
    private boolean showCandidates = false;

    /**
     * Compares leaders, sorting by toString() output.
     */
    private Comparator<Leadership> leadershipComparator = (l1, l2) ->
        String.valueOf(l1.leaderNodeId()).compareTo(String.valueOf(l2.leaderNodeId()));

    /**
     * Displays text representing the leaders.
     *
     * @param leaderBoard map of leaders
     */
    private void displayLeaders(Map<String, Leadership> leaderBoard) {
        print("------------------------------------------------------------------------");
        print(FMT, "Topic", "Leader", "Term", "Elected");
        print("------------------------------------------------------------------------");

        leaderBoard.values()
                .stream()
                .filter(l -> allTopics || pattern.matcher(l.topic()).matches())
                .filter(l -> l.leader() != null)
                .sorted(leadershipComparator)
                .forEach(l -> print(FMT,
                        l.topic(),
                        l.leaderNodeId(),
                        l.leader().term(),
                        Tools.timeAgo(l.leader().termStartTime())));
        print("------------------------------------------------------------------------");
    }

    private void displayCandidates(Map<String, Leadership> leaderBoard) {
        print("--------------------------------------------------------------------------------------------");
        print(FMT_C, "Topic", "Leader", "Term", "Elected", "Candidates");
        print("--------------------------------------------------------------------------------------------");
         leaderBoard.entrySet()
                .stream()
                .filter(es -> allTopics || pattern.matcher(es.getKey()).matches())
                .sorted((a, b) -> leadershipComparator.compare(a.getValue(), b.getValue()))
                .forEach(es -> {
                        Leadership l = es.getValue();
                        List<NodeId> candidateList = l.candidates();
                        if (candidateList == null || candidateList.isEmpty()) {
                            return;
                        }
                        print(FMT_C,
                            es.getKey(),
                            String.valueOf(l.leaderNodeId()),
                            l.leader().term(),
                            Tools.timeAgo(l.leader().termStartTime()),
                            // formatting hacks to get it into a table
                            candidateList.get(0).toString());
                            candidateList.subList(1, candidateList.size())
                                         .forEach(n -> print(FMT_C, " ", " ", " ", " ", n));
                            print(FMT_C, " ", " ", " ", " ", " ");
                        });
         print("--------------------------------------------------------------------------------------------");
    }

    /**
     * Returns JSON node representing the leaders and candidates.
     *
     * @param leaderBoard map of leaders
     */
    private JsonNode json(Map<String, Leadership> leaderBoard) {
        ObjectMapper mapper = new ObjectMapper();
        ArrayNode result = mapper.createArrayNode();
        leaderBoard.forEach((topic, leadership) -> {
                    result.add(
                            mapper.createObjectNode()
                                .put("topic", topic)
                                .put("leader", leadership.leaderNodeId() == null ?
                                        "none" : leadership.leaderNodeId().toString())
                                .put("term", leadership.leader() != null ?
                                    leadership.leader().term() : 0)
                                .put("termStartTime", leadership.leader() != null ?
                                    leadership.leader().termStartTime() : 0)
                                .put("candidates", leadership.candidates().toString()));
        });
        return result;
    }

    @Override
    protected void execute() {
        LeadershipService leaderService = get(LeadershipService.class);
        Map<String, Leadership> leaderBoard = leaderService.getLeaderBoard();
        if (topicPattern == null) {
            allTopics = true;
        } else {
            allTopics = false;
            pattern = Pattern.compile(topicPattern);
        }

        if (outputJson()) {
            print("%s", json(leaderBoard));
            return;
        }

        if (showCandidates) {
            displayCandidates(leaderBoard);
        } else {
            displayLeaders(leaderBoard);
        }
    }
}
