//
//   Copyright 2019  SenX S.A.S.
//
//   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 io.warp10.script.formatted;

import io.warp10.WarpConfig;
import io.warp10.continuum.gts.GeoTimeSerie;
import io.warp10.script.MemoryWarpScriptStack;
import io.warp10.script.WarpScriptException;
import io.warp10.script.WarpScriptLib;
import io.warp10.script.WarpScriptStack;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.StringReader;
import java.util.List;
import java.util.Map;

public class FormattedWarpScriptFunctionTest extends FormattedWarpScriptFunction {

  public FormattedWarpScriptFunctionTest() {
    super("EXAMPLE");

    //
    // Positional arguments
    //

    List<ArgumentSpecification> args = getArguments();
    args.add(new ArgumentSpecification(GeoTimeSerie.class, "1st arg","A GTS."));
    args.add(new ArgumentSpecification(Long.class, "2nd arg","A LONG."));
    args.add(new ArgumentSpecification(Double.class, "3rd arg","A DOUBLE."));

    //
    // Optional arguments
    //

    List<ArgumentSpecification> optArgs = getOptionalArguments();
    optArgs.add(new ArgumentSpecification(String.class, "1st opt arg", "The default value.", "A STRING."));

    //
    // Optional doc
    //

    StringBuilder docstring = getDocstring();
    docstring.append("This is an example implementation of FormattedWarpScriptFunction. " + getName() + " returns a map of its arguments.");

    //
    // Optional unit tests
    //

    List<String> unitTests = getUnitTests();

    StringBuilder test1 = new StringBuilder();
    test1.append("NEWGTS 3 0.5 EXAMPLE 'res' STORE" + System.lineSeparator());
    test1.append("$res '1st arg' GET TYPEOF 'GTS' == ASSERT" + System.lineSeparator());
    test1.append("$res '2nd arg' GET 3 == ASSERT" + System.lineSeparator());
    test1.append("$res '3rd arg' GET 0.5 == ASSERT" + System.lineSeparator());
    test1.append("$res SIZE 4 == ASSERT" + System.lineSeparator());
    test1.append("$res '1st opt arg' GET 'The default value.' == ASSERT");
    unitTests.add(test1.toString());

    StringBuilder test2 = new StringBuilder();
    test2.append("{ '1st arg' NEWGTS '2nd arg' 3 '3rd arg' 0.5 } EXAMPLE 'res' STORE" + System.lineSeparator());
    test2.append("$res '1st arg' GET TYPEOF 'GTS' == ASSERT" + System.lineSeparator());
    test2.append("$res '2nd arg' GET 3 == ASSERT" + System.lineSeparator());
    test2.append("$res '3rd arg' GET 0.5 == ASSERT" + System.lineSeparator());
    test2.append("$res SIZE 4 == ASSERT" + System.lineSeparator());
    test2.append("$res '1st opt arg' GET 'The default value.' == ASSERT");
    unitTests.add(test2.toString());

    StringBuilder test3 = new StringBuilder();
    test3.append("{ '1st arg' NEWGTS '2nd arg' 3 '3rd arg' 0.5 '1st opt arg' 'hi' } EXAMPLE 'res' STORE" + System.lineSeparator());
    test3.append("$res '1st arg' GET TYPEOF 'GTS' == ASSERT" + System.lineSeparator());
    test3.append("$res '2nd arg' GET 3 == ASSERT" + System.lineSeparator());
    test3.append("$res '3rd arg' GET 0.5 == ASSERT" + System.lineSeparator());
    test3.append("$res '1st opt arg' GET 'hi' == ASSERT" + System.lineSeparator());
    test3.append("$res SIZE 4 == ASSERT");
    unitTests.add(test3.toString());

  }

  //
  // The application of this function on the stack
  // formattedArgs contains positional and optional arguments
  //

  protected WarpScriptStack apply(Map<String, Object> formattedArgs, WarpScriptStack stack) throws WarpScriptException {

    stack.push(formattedArgs);
    return stack;
  }

  //
  // Running unit tests
  //

  @BeforeClass
  public static void beforeClass() throws Exception {
    StringBuilder props = new StringBuilder();

    props.append("warp.timeunits=us");
    WarpConfig.setProperties(new StringReader(props.toString()));

    WarpScriptLib.addNamedWarpScriptFunction(new FormattedWarpScriptFunctionTest());
  }

  @Test
  public void test1() throws Exception {
    MemoryWarpScriptStack stack = new MemoryWarpScriptStack(null, null);

    stack.execMulti(getUnitTests().get(0));
  }

  @Test
  public void test2() throws Exception {
    MemoryWarpScriptStack stack = new MemoryWarpScriptStack(null, null);

    stack.execMulti(getUnitTests().get(1));
  }

  @Test
  public void test3() throws Exception {
    MemoryWarpScriptStack stack = new MemoryWarpScriptStack(null, null);

    stack.execMulti(getUnitTests().get(2));
  }

}
@@ -746,154 +746,9 @@
 ipt.
-MemoryWarpScriptStack;%0Aimport io.warp10.script.WarpScriptException;%0Aimport io.warp10.script.WarpScriptLib;%0Aimport io.warp10.script.WarpScriptStack
+*
 ;%0Aim
@@ -828,16 +828,44 @@
 Reader;%0A
+import java.util.ArrayList;%0A
 import j
@@ -4806,9 +4806,592 @@
 );%0A  %7D%0A%0A
+  @Test%0A  public void test4() throws Exception %7B%0A    MemoryWarpScriptStack stack = new MemoryWarpScriptStack(null, null);%0A%0A    List%3CArgumentSpecification%3E output = new ArrayList%3C%3E();%0A    output.add(new ArgumentSpecification(Map.class, %22result%22, %22A map containing the input arguments.%22));%0A%0A    stack.execMulti(generateMc2Doc(output));%0A    stack.execMulti(%22'EXAMPLE' DEF%22);%0A%0A    try %7B%0A      stack.execMulti(%22INFOMODE EXAMPLE%22);%0A    %7D catch (WarpScriptStopException wse) %7B%0A      // do nothing%0A    %7D%0A%0A    // manual check that INFO is correct%0A    System.out.println(stack.dump(10));%0A  %7D%0A%0A
 %7D

test auto doc gen