/*
 * 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 com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
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.LeadershipAdminService;
import org.onosproject.cluster.NodeId;

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

/**
 * 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() {
        LeadershipAdminService leaderService = get(LeadershipAdminService.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);
        }
    }
}
