//
//   Copyright 2018  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.functions;

import io.warp10.script.NamedWarpScriptFunction;
import io.warp10.script.WarpScriptStackFunction;
import io.warp10.script.WarpScriptException;
import io.warp10.script.WarpScriptStack;

import java.util.List;
import java.util.Map;

/**
 * Remove an entry from a map or from a list
 */
public class REMOVE extends NamedWarpScriptFunction implements WarpScriptStackFunction {
  
  public REMOVE(String name) {
    super(name);
  }
  
  @Override
  public Object apply(WarpScriptStack stack) throws WarpScriptException {
    
    Object key = stack.pop();
    Object coll = stack.pop();

    if (coll instanceof Map) {
      if (!(key instanceof String)) {
        throw new WarpScriptException(getName() + " expects a string as key.");
      }      
      
      Object o = ((Map) coll).remove(key);

      stack.push(coll);
      stack.push(o);
    } else if (coll instanceof List) {
      if (!(key instanceof Long) && !(key instanceof Integer)) {
        throw new WarpScriptException(getName() + " expects an integer as key.");
      }      
      int idx = ((Number) key).intValue();
      
      idx = GET.computeAndCheckIndex(this, idx, ((List) coll).size());

      Object o = ((List) coll).remove(idx);

      stack.push(coll);
      stack.push(o);
    } else {
      throw new WarpScriptException(getName() + " operates on a map or a list.");      
    }
    
    return stack;
  }
}

@@ -1676,30 +1676,24 @@
 .%22);%0A      %7D
-      
 %0A      int i
@@ -1728,22 +1728,16 @@
 ();%0A
-      
 %0A      i
 dx =
@@ -1736,85 +1736,158 @@
    i
-dx = GET.computeAndCheckIndex(this, idx, ((List) coll).size());%0A%0A      Object
+nt size = ((List) coll).size();%0A%0A      if (idx %3C 0) %7B%0A        idx += size;%0A      %7D%0A%0A      Object o = null;%0A      if (idx %3E= 0 && idx %3C size) %7B%0A       
  o =
@@ -1914,16 +1914,30 @@
 e(idx);%0A
+      %7D%0A      
 %0A      s

Revert REMOVE behavior to returning null outside [-size;size-1]