/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

package foam.nanos.test;

import bsh.EvalError;
import bsh.Interpreter;
import foam.core.*;
import foam.dao.*;
import foam.nanos.NanoService;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Date;
import foam.mlang.MLang.*;
import java.io.IOException;

public class TestRunner
  extends    ContextAwareSupport
  implements NanoService
{

  public void start() {
    final MapDAO tests = (MapDAO) getX().get("TestDAO");
    /* TODO add listener for when test is scheduled
    */
    runAllTests();
  }

  public Test runTest(Test test) {
    ByteArrayOutputStream bas   = new ByteArrayOutputStream();
    PrintStream           ps    = new PrintStream(bas);
    final Interpreter     shell = new Interpreter(); // Creates a new Interpreter at each call

    try {
      shell.set("currentTest", test);
      test.setPassed(0);
      test.setFailed(0);
      test.setOutput("");
      shell.setOut(ps);

      // creates the testing method
      shell.eval("test(boolean exp, String message) { if ( exp ) { currentTest.setPassed(currentTest.getPassed()+1); } else currentTest.setFailed(currentTest.getFailed()+1); print((exp ? \"SUCCESS: \" : \"FAILURE: \")+message);}");
      shell.eval(test.getCode());
    } catch (EvalError e) {
      e.printStackTrace();
    }
    test.setLastRun(new Date());
    ps.flush();
    test.setOutput(bas.toString());
    test.setScheduled(false);
    // increment lastRun, success, failures
    return test;
  }

  public void runAllTests() {
    final MapDAO tests = (MapDAO) getX().get("TestDAO");
    try {
      final JournaledDAO jTests = new JournaledDAO(tests,"TestFile.jrl");
      ((AbstractDAO) tests.where(foam.mlang.MLang.EQ(Test.SCHEDULED, Boolean.TRUE))).select(new AbstractSink() {
        public void put(FObject o, Detachable sub) {
          Test     test  = (Test) o;
          test = runTest(test);
          jTests.put(test);
        }
      });
    } catch (IOException e){
      e.printStackTrace();
    }
  }

  public static void main(String[] args){
    MapDAO tests = new MapDAO();
    X      x     = EmptyX.instance().put("TestDAO", tests);
    tests.setX(x);
    tests.setOf(Test.getOwnClassInfo());
    try {
      JournaledDAO jTests = new JournaledDAO(tests,"TestFile.jrl");
      Test test1 = new Test();
      test1.setId("Test 1");
      test1.setCode("test(2==2 ,\"TRUE\");");  
      jTests.put(test1);
      Test test2 = new Test();
      test2.setId("Test 2");
      test2.setCode("test(1==2 ,\"FALSE\");");  
      test2.setScheduled(true);
      jTests.put(test2);
      Test test3 = new Test();
      test3.setId("Test 3");
      test3.setCode("print(\"All Done.\");");  
      jTests.put(test3);
      TestRunner runner = new TestRunner();
      runner.setX(x);
      runner.start();
    } catch (IOException e){
      e.printStackTrace();
    }
    
  }
}

@@ -577,16 +577,21 @@
 %0A    /* 
+%0A    
 TODO add
@@ -2333,16 +2333,22 @@
 %7B%0A      
+final 
 Journale
@@ -2398,32 +2398,35 @@
 ile.jrl%22);%0A     
+ //
  Test test1 = ne
@@ -2432,32 +2432,35 @@
 ew Test();%0A     
+ //
  test1.setId(%22Te
@@ -2468,24 +2468,27 @@
 t 1%22);%0A     
+ //
  test1.setCo
@@ -2515,32 +2515,35 @@
 E%5C%22);%22);  %0A     
+ //
  jTests.put(test
@@ -2543,32 +2543,35 @@
 ut(test1);%0A     
+ //
  Test test2 = ne
@@ -2577,32 +2577,35 @@
 ew Test();%0A     
+ //
  test2.setId(%22Te
@@ -2613,24 +2613,27 @@
 t 2%22);%0A     
+ //
  test2.setCo
@@ -2674,39 +2674,10 @@
     
-test2.setScheduled(true);%0A     
+//
  jTe
@@ -2693,24 +2693,27 @@
 est2);%0A     
+ //
  Test test3 
@@ -2723,32 +2723,35 @@
 ew Test();%0A     
+ //
  test3.setId(%22Te
@@ -2759,24 +2759,27 @@
 t 3%22);%0A     
+ //
  test3.setCo
@@ -2810,24 +2810,27 @@
 ;%22);  %0A     
+ //
  jTests.put(
@@ -2837,16 +2837,303 @@
 test3);%0A
+      ((AbstractDAO) tests.where(foam.mlang.MLang.EQ(Test.SCHEDULED, Boolean.FALSE))).select(new AbstractSink() %7B%0A        public void put(FObject o, Detachable sub) %7B%0A          Test     test  = (Test) o;%0A          test.setScheduled(true);%0A          jTests.put(test);%0A        %7D%0A      %7D);%0A
       Te

set up main to demo testrunner