/*
 * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.controller.cluster.raft;

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.pattern.Patterns;
import akka.testkit.JavaTestKit;
import akka.util.Timeout;
import com.google.common.util.concurrent.Uninterruptibles;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.junit.Assert;
import org.opendaylight.controller.cluster.raft.client.messages.FindLeader;
import org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.concurrent.Await;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
import scala.concurrent.duration.FiniteDuration;

public class RaftActorTestKit extends JavaTestKit {
    private static final Logger LOG = LoggerFactory.getLogger(RaftActorTestKit.class);
    private final ActorRef raftActor;

    public RaftActorTestKit(ActorSystem actorSystem, String actorName) {
        super(actorSystem);

        raftActor = this.getSystem().actorOf(MockRaftActor.builder().id(actorName).props(), actorName);

    }


    public ActorRef getRaftActor() {
        return raftActor;
    }

    public boolean waitForLogMessage(final Class<?> logEventClass, String message) {
        // Wait for a specific log message to show up
        return
            new JavaTestKit.EventFilter<Boolean>(logEventClass
            ) {
                @Override
                protected Boolean run() {
                    return true;
                }
            }.from(raftActor.path().toString())
                .message(message)
                .occurrences(1).exec();


    }

    protected void waitUntilLeader() {
        waitUntilLeader(raftActor);
    }

    @SuppressWarnings("checkstyle:IllegalCatch")
    public static void waitUntilLeader(ActorRef actorRef) {
        FiniteDuration duration = Duration.create(100, TimeUnit.MILLISECONDS);
        for (int i = 0; i < 20 * 5; i++) {
            Future<Object> future = Patterns.ask(actorRef, FindLeader.INSTANCE, new Timeout(duration));
            try {
                final Optional<String> maybeLeader = ((FindLeaderReply)Await.result(future, duration)).getLeaderActor();
                if (maybeLeader.isPresent()) {
                    return;
                }
            } catch (Exception e) {
                LOG.error("FindLeader failed", e);
            }

            Uninterruptibles.sleepUninterruptibly(50, TimeUnit.MILLISECONDS);
        }

        Assert.fail("Leader not found for actorRef " + actorRef.path());
    }

}

@@ -461,20 +461,65 @@
 testkit.
-Java
+javadsl.EventFilter;%0Aimport akka.testkit.javadsl.
 TestKit;
@@ -1102,20 +1102,16 @@
 extends 
-Java
 TestKit 
@@ -1266,16 +1266,22 @@
 TestKit(
+final 
 ActorSys
@@ -1296,16 +1296,22 @@
 rSystem,
+ final
  String 
@@ -1351,17 +1351,16 @@
 ystem);%0A
-%0A
         
@@ -1459,17 +1459,15 @@
 e);%0A
-%0A
     %7D%0A%0A
-%0A
     
@@ -1598,16 +1598,22 @@
 ntClass,
+ final
  String 
@@ -1695,37 +1695,13 @@
 turn
-%0A            new JavaTestKit.
+ new 
 Even
@@ -1711,17 +1711,8 @@
 lter
-%3CBoolean%3E
 (log
@@ -1725,157 +1725,22 @@
 lass
-%0A            ) %7B%0A                @Override%0A                protected Boolean run() %7B%0A                    return true;%0A                %7D%0A            %7D
+, getSystem())
 .fro
@@ -1769,33 +1769,16 @@
 tring())
-%0A                
 .message
@@ -1823,17 +1823,38 @@
 (1).
-exec();%0A%0A
+intercept(() -%3E Boolean.TRUE);
 %0A   
@@ -2027,16 +2027,22 @@
 lLeader(
+final 
 ActorRef
@@ -2782,11 +2782,10 @@
 ;%0A    %7D%0A
-%0A
 %7D%0A

Migrate RaftActorTestKit to javadsl.TestKit