/*
 * 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.store.primitives.impl;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.Collection;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;

import org.onosproject.cluster.Leadership;
import org.onosproject.cluster.NodeId;
import org.onosproject.cluster.PartitionId;
import org.onosproject.event.Change;
import org.onosproject.store.service.AsyncLeaderElector;

import com.google.common.collect.Maps;

/**
 * {@link AsyncLeaderElector} that has its topics partitioned horizontally across
 * several {@link AsyncLeaderElector leader electors}.
 */
public class PartitionedAsyncLeaderElector implements AsyncLeaderElector {

    private final String name;
    private final TreeMap<PartitionId, AsyncLeaderElector> partitions = Maps.newTreeMap();
    private final Hasher<String> topicHasher;

    public PartitionedAsyncLeaderElector(String name,
            Map<PartitionId, AsyncLeaderElector> partitions,
            Hasher<String> topicHasher) {
        this.name = name;
        this.partitions.putAll(checkNotNull(partitions));
        this.topicHasher = checkNotNull(topicHasher);
    }

    @Override
    public String name() {
        return name;
    }

    @Override
    public CompletableFuture<Leadership> run(String topic, NodeId nodeId) {
        return getLeaderElector(topic).run(topic, nodeId);
    }

    @Override
    public CompletableFuture<Void> withdraw(String topic) {
        return getLeaderElector(topic).withdraw(topic);
    }

    @Override
    public CompletableFuture<Boolean> anoint(String topic, NodeId nodeId) {
        return getLeaderElector(topic).anoint(topic, nodeId);
    }

    @Override
    public CompletableFuture<Boolean> promote(String topic, NodeId nodeId) {
        return getLeaderElector(topic).promote(topic, nodeId);
    }

    @Override
    public CompletableFuture<Void> evict(NodeId nodeId) {
        return CompletableFuture.allOf(getLeaderElectors().stream()
                                                          .map(le -> le.evict(nodeId))
                                                          .toArray(CompletableFuture[]::new));
    }

    @Override
    public CompletableFuture<Leadership> getLeadership(String topic) {
        return getLeaderElector(topic).getLeadership(topic);
    }

    @Override
    public CompletableFuture<Map<String, Leadership>> getLeaderships() {
        Map<String, Leadership> leaderships = Maps.newConcurrentMap();
        return CompletableFuture.allOf(getLeaderElectors().stream()
                                                          .map(le -> le.getLeaderships()
                                                                       .thenAccept(m -> leaderships.putAll(m)))
                                                          .toArray(CompletableFuture[]::new))
                                .thenApply(v -> leaderships);
    }

    @Override
    public CompletableFuture<Void> addChangeListener(Consumer<Change<Leadership>> listener) {
        return CompletableFuture.allOf(getLeaderElectors().stream()
                                                          .map(map -> map.addChangeListener(listener))
                                                          .toArray(CompletableFuture[]::new));
    }

    @Override
    public CompletableFuture<Void> removeChangeListener(Consumer<Change<Leadership>> listener) {
        return CompletableFuture.allOf(getLeaderElectors().stream()
                                                          .map(map -> map.removeChangeListener(listener))
                                                          .toArray(CompletableFuture[]::new));
    }

    /**
     * Returns the leaderElector (partition) to which the specified topic maps.
     * @param topic topic name
     * @return AsyncLeaderElector to which topic maps
     */
    private AsyncLeaderElector getLeaderElector(String topic) {
        return partitions.get(topicHasher.hash(topic));
    }

    /**
     * Returns all the constituent leader electors.
     * @return collection of leader electors.
     */
    private Collection<AsyncLeaderElector> getLeaderElectors() {
        return partitions.values();
    }
}