/* Copyright (C) 2013-2017 TU Dortmund
 * This file is part of LearnLib, http://www.learnlib.de/.
 *
 * 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 de.learnlib.testsupport.it.learner;

import de.learnlib.api.EquivalenceOracle;
import de.learnlib.api.LearningAlgorithm;
import de.learnlib.eqtests.basic.SimulatorEQOracle;
import de.learnlib.examples.LearningExample;
import de.learnlib.oracles.DefaultQuery;
import net.automatalib.automata.UniversalDeterministicAutomaton;
import net.automatalib.automata.concepts.SuffixOutput;
import net.automatalib.util.automata.Automata;
import net.automatalib.words.Alphabet;
import org.testng.Assert;
import org.testng.ITest;
import org.testng.annotations.Test;

final class LearnerVariantITCase<I, D, M extends UniversalDeterministicAutomaton<?, I, ?, ?, ?> & SuffixOutput<I, D>>
        implements ITest {

    private static final long NANOS_PER_MILLISECOND = 1000000;
    private static final long MILLIS_PER_SECOND = 1000;

    private final LearnerVariant<? extends M, I, D> variant;
    private final LearningExample<I, D, ? extends M> example;

    LearnerVariantITCase(LearnerVariant<? extends M, I, D> variant, LearningExample<I, D, ? extends M> example) {
        this.variant = variant;
        this.example = example;
    }

    @Test
    public void testLearning() {
        System.out.print("Running learner integration test " + getTestName() + " ... ");
        System.out.flush();

        LearningAlgorithm<? extends M, I, D> learner = variant.getLearner();

        Alphabet<I> alphabet = example.getAlphabet();

        int maxRounds = variant.getMaxRounds();
        if (maxRounds < 0) {
            maxRounds = example.getReferenceAutomaton().size();
        }

        EquivalenceOracle<? super M, I, D> eqOracle = new SimulatorEQOracle<>(example.getReferenceAutomaton());

        long start = System.nanoTime();

        learner.startLearning();

        int roundCounter = 0;
        DefaultQuery<I, D> ceQuery;

        while ((ceQuery = eqOracle.findCounterExample(learner.getHypothesisModel(), alphabet)) != null) {
            roundCounter++;
            if (roundCounter > maxRounds) {
                Assert.fail("Learning took too many rounds (> " + maxRounds + ")");
            }

            boolean refined = learner.refineHypothesis(ceQuery);
            Assert.assertTrue(refined, "Real counterexample " + ceQuery.getInput() + " did not refine hypothesis");
        }

        Assert.assertNull(Automata.findSeparatingWord(example.getReferenceAutomaton(),
                                                      learner.getHypothesisModel(),
                                                      alphabet), "Final hypothesis does not match reference automaton");

        long duration = (System.nanoTime() - start) / NANOS_PER_MILLISECOND;
        System.out.printf("ok [%d.%03ds]", duration / MILLIS_PER_SECOND, duration % MILLIS_PER_SECOND);
        System.out.println();
    }

    @Override
    public String getTestName() {
        return variant.getLearnerName() + "[" + variant.getName() + "]/" + example.getClass().getSimpleName();
    }

}

@@ -1126,16 +1126,73 @@
 phabet;%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A
 import o
@@ -1417,16 +1417,111 @@
 Test %7B%0A%0A
+    private static final Logger LOGGER = LoggerFactory.getLogger(LearnerVariantITCase.class);%0A%0A
     priv
@@ -1988,126 +1988,8 @@
 ) %7B%0A
-        System.out.print(%22Running learner integration test %22 + getTestName() + %22 ... %22);%0A        System.out.flush();%0A%0A
     
@@ -3375,39 +3375,150 @@
     
-System.out.printf(%22ok %5B
+LOGGER.info(%22Passed learner integration test %7B%7D ... took %5B%7B%7D%5D%22,%0A                    getTestName(),%0A                    String.format(%22
 %25d.%2503ds
 %5D%22, 
@@ -3513,17 +3513,16 @@
 %25d.%2503ds
-%5D
 %22, durat
@@ -3579,37 +3579,8 @@
 OND)
-;%0A        System.out.println(
 );%0A 

use logger instead of system.out