package com.intuit.karate.junit4;

import com.intuit.karate.Resource;
import com.intuit.karate.FileUtils;
import com.intuit.karate.RunnerOptions;
import com.intuit.karate.core.Engine;
import com.intuit.karate.core.Feature;
import com.intuit.karate.core.FeatureParser;
import com.intuit.karate.core.FeatureResult;
import com.intuit.karate.core.Scenario;
import com.intuit.karate.core.ScenarioResult;
import com.intuit.karate.core.Tags;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.ParentRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author pthomas3
 */
public class Karate extends ParentRunner<Feature> {

    private static final Logger logger = LoggerFactory.getLogger(Karate.class);

    private final List<Feature> children;
    private final String tagSelector;

    public Karate(Class<?> clazz) throws InitializationError, IOException {
        super(clazz);
        List<FrameworkMethod> testMethods = getTestClass().getAnnotatedMethods(Test.class);
        if (!testMethods.isEmpty()) {
            logger.warn("WARNING: there are methods annotated with '@Test', they will NOT be run when using '@RunWith(Karate.class)'");
        }
        RunnerOptions options = RunnerOptions.fromAnnotationAndSystemProperties(clazz);
        List<Resource> resources = FileUtils.scanForFeatureFiles(options.getFeatures(), clazz.getClassLoader());
        children = new ArrayList(resources.size());
        for (Resource resource : resources) {
            Feature feature = FeatureParser.parse(resource);
            children.add(feature);
        }
        tagSelector = Tags.fromCucumberOptionsTags(options.getTags());
    }

    @Override
    public List<Feature> getChildren() {
        return children;
    }

    private static Description getScenarioDescription(String featureName, Scenario scenario) {
        return Description.createTestDescription(featureName, scenario.getDisplayMeta() + ' ' + scenario.getName());
    }

    private static String getFeatureName(Feature feature) {
        return "[" + feature.getResource().getFileNameWithoutExtension() + "]";
    }

    @Override
    protected Description describeChild(Feature child) {
        return Description.createSuiteDescription(getFeatureName(child), child.getResource().getPackageQualifiedName());
    }

    @Override
    protected void runChild(Feature child, RunNotifier notifier) {
        FeatureResult result = Engine.executeFeatureSync(child, tagSelector, null);
        for (ScenarioResult sr : result.getScenarioResults()) {
            Description scenarioDescription = getScenarioDescription(getFeatureName(child), sr.getScenario());
            notifier.fireTestStarted(scenarioDescription);
            if (sr.isFailed()) {
                notifier.fireTestFailure(new Failure(scenarioDescription, sr.getError()));
            }
            notifier.fireTestFinished(scenarioDescription);
        }
        Engine.saveResultHtml(Engine.getBuildDir() + File.separator + "surefire-reports", result);
    }

    @Override
    public void run(RunNotifier notifier) {
        super.run(notifier);
    }

}

@@ -522,20 +522,68 @@
 va.util.
-List
+HashMap;%0Aimport java.util.List;%0Aimport java.util.Map
 ;%0Aimport
@@ -1132,24 +1132,79 @@
 %3E children;%0A
+    private final Map%3CString, Description%3E featureMap;%0A
     private 
@@ -1853,24 +1853,76 @@
 es.size());%0A
+        featureMap = new HashMap(resources.size());%0A
         for 
@@ -2047,24 +2047,513 @@
 d(feature);%0A
+            Description featureDescription = Description.createSuiteDescription(%0A                    getFeatureName(feature), feature.getResource().getPackageQualifiedName());%0A            featureMap.put(feature.getRelativePath(), featureDescription);%0A            for (Scenario s : feature.getScenarios()) %7B%0A                Description scenarioDescription = getScenarioDescription(getFeatureName(feature), s);%0A                featureDescription.addChild(scenarioDescription);%0A            %7D%0A
         %7D%0A  
@@ -3171,109 +3171,44 @@
 urn 
-Description.createSuiteDescription(getFeatureName(child), child.getResource().getPackageQualifiedName
+featureMap.get(child.getRelativePath
 ());

fix for eclipse junit ui unrooted tests #542