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

import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import com.google.common.collect.Maps;
import io.atomix.core.election.LeadershipEventListener;
import org.onosproject.cluster.Leader;
import org.onosproject.cluster.Leadership;
import org.onosproject.cluster.NodeId;
import org.onosproject.event.Change;
import org.onosproject.store.service.AsyncLeaderElector;

/**
 * Atomix leader elector.
 */
public class AtomixLeaderElector implements AsyncLeaderElector {
    private final io.atomix.core.election.AsyncLeaderElector<NodeId> atomixElector;
    private final NodeId localNodeId;
    private final Map<Consumer<Change<Leadership>>, LeadershipEventListener<NodeId>> listenerMap =
        Maps.newIdentityHashMap();

    public AtomixLeaderElector(io.atomix.core.election.AsyncLeaderElector<NodeId> atomixElector, NodeId localNodeId) {
        this.atomixElector = atomixElector;
        this.localNodeId = localNodeId;
    }

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

    @Override
    public CompletableFuture<Leadership> run(String topic, NodeId nodeId) {
        return atomixElector.run(topic, nodeId).thenApply(leadership -> toLeadership(topic, leadership));
    }

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

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

    @Override
    public CompletableFuture<Void> evict(NodeId nodeId) {
        return atomixElector.evict(nodeId);
    }

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

    @Override
    public CompletableFuture<Leadership> getLeadership(String topic) {
        return atomixElector.getLeadership(topic).thenApply(leadership -> toLeadership(topic, leadership));
    }

    @Override
    public CompletableFuture<Map<String, Leadership>> getLeaderships() {
        return atomixElector.getLeaderships()
            .thenApply(leaderships -> leaderships.entrySet().stream()
                .collect(Collectors.toMap(e -> e.getKey(), e -> toLeadership(e.getKey(), e.getValue()))));
    }

    @Override
    public CompletableFuture<Void> addChangeListener(Consumer<Change<Leadership>> consumer) {
        LeadershipEventListener<NodeId> atomixListener = event ->
            consumer.accept(new Change<>(
                toLeadership(event.topic(), event.oldLeadership()),
                toLeadership(event.topic(), event.newLeadership())));
        listenerMap.put(consumer, atomixListener);
        return atomixElector.addListener(atomixListener);
    }

    @Override
    public CompletableFuture<Void> removeChangeListener(Consumer<Change<Leadership>> consumer) {
        LeadershipEventListener<NodeId> atomixListener = listenerMap.remove(consumer);
        if (atomixListener != null) {
            return atomixElector.removeListener(atomixListener);
        }
        return CompletableFuture.completedFuture(null);
    }

    private Leadership toLeadership(String topic, io.atomix.core.election.Leadership<NodeId> leadership) {
        return leadership != null
            ? new Leadership(topic, toLeader(leadership.leader()), leadership.candidates())
            : null;
    }

    private Leader toLeader(io.atomix.core.election.Leader<NodeId> leader) {
        return leader != null ? new Leader(leader.id(), leader.term(), leader.timestamp()) : null;
    }
}
