package com.hubspot.jinjava.lib.filter;

import com.hubspot.jinjava.doc.annotations.JinjavaDoc;
import com.hubspot.jinjava.doc.annotations.JinjavaParam;
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
import com.hubspot.jinjava.interpret.InvalidArgumentException;
import com.hubspot.jinjava.interpret.InvalidReason;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.interpret.TemplateSyntaxException;
import com.hubspot.jinjava.lib.exptest.ExpTest;
import com.hubspot.jinjava.util.ForLoop;
import com.hubspot.jinjava.util.ObjectIterator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@JinjavaDoc(
  value = "Filters a sequence of objects by applying a test to the object and rejecting the ones with the test succeeding.",
  input = @JinjavaParam(value = "seq", type = "Sequence to test", required = true),
  params = {
    @JinjavaParam(
      value = "exp_test",
      type = "name of expression test",
      desc = "Specify which expression test to run for making the selection",
      required = true
    )
  },
  snippets = {
    @JinjavaSnippet(
      code = "{% set some_numbers = [10, 12, 13, 3, 5, 17, 22] %}\n" +
      "{% some_numbers|reject('even') %}"
    )
  }
)
public class RejectFilter implements Filter {

  @Override
  public String getName() {
    return "reject";
  }

  @Override
  public Object filter(Object var, JinjavaInterpreter interpreter, String... args) {
    List<Object> result = new ArrayList<>();

    if (args.length < 1) {
      throw new TemplateSyntaxException(
        interpreter,
        getName(),
        "requires 1 argument (name of expression test to filter by)"
      );
    }

    if (args[0] == null) {
      throw new InvalidArgumentException(interpreter, this, InvalidReason.NULL, 0);
    }

    Object[] expArgs = new Object[] {};

    if (args.length > 1) {
      expArgs = Arrays.copyOfRange(args, 1, args.length);
    }

    ExpTest expTest = interpreter.getContext().getExpTest(args[0]);
    if (expTest == null) {
      throw new InvalidArgumentException(
        interpreter,
        this,
        InvalidReason.EXPRESSION_TEST,
        0,
        args[0]
      );
    }

    ForLoop loop = ObjectIterator.getLoop(var);
    while (loop.hasNext()) {
      Object val = loop.next();

      if (!expTest.evaluate(val, interpreter, expArgs)) {
        result.add(val);
      }
    }

    return result;
  }
}

@@ -651,16 +651,38 @@
 il.List;
+%0Aimport java.util.Map;
 %0A%0A@Jinja
@@ -1304,16 +1304,24 @@
 lements 
+Advanced
 Filter %7B
@@ -1423,16 +1423,21 @@
  filter(
+%0A    
 Object v
@@ -1439,16 +1439,20 @@
 ect var,
+%0A   
  Jinjava
@@ -1479,23 +1479,61 @@
 ter,
- String... 
+%0A    Object%5B%5D args,%0A    Map%3CString, Object%3E kw
 args
+%0A  
 ) %7B%0A
@@ -2018,24 +2018,24 @@
 th);%0A    %7D%0A%0A
-
     ExpTest 
@@ -2087,16 +2087,27 @@
 (args%5B0%5D
+.toString()
 );%0A    i

Make RejectFilter more like SelectFilter