/*
 * Copyright 2018 Red Hat, Inc. and/or its affiliates.
 *
 * 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.drools.benchmarks.manual;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

import org.drools.benchmarks.common.DRLProvider;
import org.drools.benchmarks.common.providers.RulesWithJoinsProvider;
import org.drools.benchmarks.common.providers.SimpleRulesWithConstraintProvider;
import org.drools.benchmarks.common.util.BuildtimeUtil;
import org.kie.api.KieBase;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.KieServices;
import org.kie.api.builder.ReleaseId;
import org.kie.api.io.Resource;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.util.FileUtils;

@State(Scope.Thread)
@BenchmarkMode(Mode.SingleShotTime)
//@Warmup(iterations = 15, time = 2, timeUnit = TimeUnit.SECONDS)
//@Measurement(iterations = 15, time = 2, timeUnit = TimeUnit.SECONDS)
@Warmup(iterations = 500)
@Measurement(iterations = 15)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class BuildKieBaseFromContainerManyRulesBenchmark {

    @Param({"false"})
    private boolean useCanonicalModel;

    @Param({"200"})
    private int numberOfRulesPerFile;

    @Param({"100"})
    private int numberOfRuleFiles;

    @Param({SimpleRulesWithConstraintProvider.PROVIDER_ID, RulesWithJoinsProvider.PROVIDER_ID})
    private String rulesProviderId;

    private ReleaseId releaseId;
    private KieServices kieServices;
    private KieBaseConfiguration kieBaseConfiguration;

    @Setup
    public void createKJar() throws IOException {
        kieServices = KieServices.get();
        kieBaseConfiguration = kieServices.newKieBaseConfiguration();
        final Collection<Resource> ruleResources = generateRuleResources();
        System.out.println("Creating KJar...");
        releaseId = BuildtimeUtil.createKJarFromResources(useCanonicalModel, ruleResources.toArray(new Resource[]{}));
    }

    @Benchmark
    public KieBase getKieBaseFromContainer() {
        return kieServices.newKieContainer(releaseId).newKieBase(kieBaseConfiguration);
    }

    private Collection<Resource> generateRuleResources() {
        final DRLProvider drlProvider = getDRLProvider();
        final Map<Integer, Resource> resourcesMap = new ConcurrentHashMap<>();
        IntStream.range(1, numberOfRuleFiles + 1).parallel().forEach(ruleFileId -> {
            final String drl = drlProvider.getDrl(numberOfRulesPerFile, "R" + ruleFileId + "-");
            final List<String> lines = Arrays.asList(drl.split("\n"));
            try {
                final String drlFilePath = FileUtils.createTempFileWithLines("drlFile-R" + ruleFileId + ".drl", lines);
                final Resource drlResource = KieServices.get().getResources().newFileSystemResource(new File(drlFilePath));
                resourcesMap.put(ruleFileId, drlResource);
            } catch (IOException e) {
                e.printStackTrace();
            }
//            final Resource drlResource = KieServices.get().getResources()
//                    .newReaderResource(new StringReader(drlProvider.getDrl(numberOfRulesPerFile, "R" + ruleFileId + "-")))
//                    .setResourceType(ResourceType.DRL)
//                    .setSourcePath("drlFile" + ruleFileId + ".drl");
//            resourcesMap.put(ruleFileId, drlResource);
        });
        return resourcesMap.values();
    }

    private DRLProvider getDRLProvider() {
        switch (rulesProviderId) {
            case SimpleRulesWithConstraintProvider.PROVIDER_ID:
                return new SimpleRulesWithConstraintProvider("Integer(this == ${i})");
            case RulesWithJoinsProvider.PROVIDER_ID:
                return new RulesWithJoinsProvider(4, false, true);
            default:
                throw new IllegalArgumentException("Benchmark doesn't support rules provider with id: " + rulesProviderId + "!");
        }
    }
}

@@ -1441,24 +1441,65 @@
 chmarkMode;%0A
+import org.openjdk.jmh.annotations.Fork;%0A
 import org.o
@@ -1934,18 +1934,16 @@
 otTime)%0A
-//
 @Warmup(
@@ -1948,33 +1948,33 @@
 p(iterations = 1
-5
+0
 , time = 2, time
@@ -1993,19 +1993,17 @@
 nit.
-SECOND
+MINUTE
 S)%0A
-//
 @Mea
@@ -2062,71 +2062,24 @@
 nit.
-SECONDS)%0A@Warmup(iterations = 500)%0A@Measurement(iterations = 15
+MINUTES)%0A@Fork(2
 )%0A@O
@@ -2175,16 +2175,16 @@
 mark %7B%0A%0A
-
     @Par
@@ -2187,16 +2187,24 @@
 @Param(%7B
+%22true%22, 
 %22false%22%7D
@@ -4061,394 +4061,8 @@
   %7D%0A
-//            final Resource drlResource = KieServices.get().getResources()%0A//                    .newReaderResource(new StringReader(drlProvider.getDrl(numberOfRulesPerFile, %22R%22 + ruleFileId + %22-%22)))%0A//                    .setResourceType(ResourceType.DRL)%0A//                    .setSourcePath(%22drlFile%22 + ruleFileId + %22.drl%22);%0A//            resourcesMap.put(ruleFileId, drlResource);%0A
     

Change iterations count for a very long running benchmark