package com.test;

import java.io.StringReader;
import java.util.concurrent.TimeUnit;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.conf.EventProcessingOption;
import org.drools.io.ResourceFactory;
import org.drools.runtime.KnowledgeSessionConfiguration;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.conf.ClockTypeOption;
import org.drools.runtime.rule.WorkingMemoryEntryPoint;
import org.drools.time.SessionPseudoClock;

public class TimerTest {
    public class Foo {
        private long timestamp;

        public Foo(long timestamp) {
            this.timestamp = timestamp;
        }

        public long getTimestamp() {
            return timestamp;
        }

        public void setValue(long timestamp) {
            this.timestamp = timestamp;
        }
    }

    private static String rule = 
        "import com.test.TimerTest.Foo\n" +
        "global Long time\n" + 
        "declare Foo @role (event) @expires (5s) @timestamp(timestamp) end\n" +
        "rule test\n" +
        "timer (int: 5s)\n" +
        "when\n" +
        "   $count : Number() from accumulate(\n" +
        "       $f : Foo()\n" +
        "       over window:time(5000ms)\n" +
        "       from entry-point EntryPoint\n" +
        "       count($f)\n" +
        "   )" +
        "then\n" +
        "   System.out.println(\"count = \" + $count + \", time = \" + time + \"ms\");\n" +
        "end";

    public TimerTest() {

        KnowledgeBaseConfiguration kbaseConf = KnowledgeBaseFactory
            .newKnowledgeBaseConfiguration();

        kbaseConf.setOption(EventProcessingOption.STREAM);
            
        KnowledgeBuilder builder = KnowledgeBuilderFactory
            .newKnowledgeBuilder();
            
        builder.add(ResourceFactory.newReaderResource(new StringReader(rule)),
            ResourceType.DRL);

        if (builder.hasErrors()) {
            throw new RuntimeException(builder.getErrors().toString());
        }

        final KnowledgeBase knowledgeBase = KnowledgeBaseFactory
            .newKnowledgeBase(kbaseConf);

        knowledgeBase.addKnowledgePackages(builder.getKnowledgePackages());
          
        final KnowledgeSessionConfiguration config = KnowledgeBaseFactory
                .newKnowledgeSessionConfiguration();
        
        config.setOption(ClockTypeOption.get("pseudo"));
        
        StatefulKnowledgeSession session = knowledgeBase
                .newStatefulKnowledgeSession(config, null);

        SessionPseudoClock clock = session.getSessionClock();

        WorkingMemoryEntryPoint entryPoint = session
                .getWorkingMemoryEntryPoint("EntryPoint");
            
        for (long i = 1; i <= 16; i++) {
            clock.advanceTime(1, TimeUnit.SECONDS);
            
            session.setGlobal("time", clock.getCurrentTime());
            entryPoint.insert(new Foo(i * 1000));
            session.fireAllRules();
        }
    }
    
    public static void main(String [] args) {
        new TimerTest();
    }
}

