//
//   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 java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

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

public class ERROR extends NamedWarpScriptFunction implements WarpScriptStackFunction {
  
  public ERROR(String name) {
    super(name);
  }
  
  @Override
  public Object apply(WarpScriptStack stack) throws WarpScriptException {
    
    Throwable t = (Throwable) stack.getAttribute(WarpScriptStack.ATTRIBUTE_LAST_ERROR);
    
    // List of errors (with cause for each one)
    List<Object> errlist = new ArrayList<Object>();
    
    // Set to make sure we don't have cycles
    Set<Throwable> throwables = new HashSet<Throwable>();
    
    while(null != t && !throwables.contains(t)) {
      Map<String,Object> err = new HashMap<String,Object>();
      
      List<Object> trace = new ArrayList<Object>();
      
      if (null != t) {
        StackTraceElement[] st = t.getStackTrace();

        if (null != st) {
          for (StackTraceElement elt: st) {
            String className = elt.getClassName();
            int lineNumber = elt.getLineNumber();
            String methodName = elt.getMethodName();
            String fileName = elt.getFileName();
            
            List<Object> elts = new ArrayList<Object>();
            
            elts.add(fileName);
            elts.add(lineNumber);
            elts.add(className);
            elts.add(methodName);
            
            trace.add(elts);
          }        
        }
        
        err.put("type", t.getClass().toString());
        err.put("message", t.getMessage());
        err.put("stacktrace", trace);      
      }

      throwables.add(t);
      
      t = t.getCause();
      
      errlist.add(err);
    }
    
    stack.push(errlist);
    
    return stack;
  }
}

@@ -1700,33 +1700,8 @@
    %0A
-      if (null != t) %7B%0A  
     
@@ -1753,18 +1753,16 @@
 %0A%0A      
-  
 if (null
@@ -1779,18 +1779,16 @@
         
- 
- 
 for (Sta
@@ -1809,26 +1809,24 @@
  elt: st) %7B%0A
-  
           St
@@ -1872,18 +1872,16 @@
         
- 
- 
 int line
@@ -1906,26 +1906,24 @@
 neNumber();%0A
-  
           St
@@ -1967,26 +1967,24 @@
 ;%0A          
- 
- 
 String fileN
@@ -2004,39 +2004,25 @@
 FileName();%0A
-            %0A  
+%0A
           Li
@@ -2064,28 +2064,16 @@
 ect%3E();%0A
-            
 %0A       
@@ -2067,34 +2067,32 @@
 %3E();%0A%0A          
-  
 elts.add(fileNam
@@ -2091,26 +2091,24 @@
 (fileName);%0A
-  
           el
@@ -2129,34 +2129,32 @@
 ber);%0A          
-  
 elts.add(classNa
@@ -2154,26 +2154,24 @@
 className);%0A
-  
           el
@@ -2194,23 +2194,9 @@
 e);%0A
-            %0A  
+%0A
     
@@ -2230,41 +2230,19 @@
     
-  %7D        %0A        %7D%0A        %0A  
+%7D%0A      %7D%0A%0A
     
@@ -2283,34 +2283,32 @@
 tring());%0A      
-  
 err.put(%22message
@@ -2329,26 +2329,24 @@
 e());%0A      
- 
- 
 err.put(%22sta
@@ -2366,22 +2366,8 @@
 ce);
-      %0A      %7D
 %0A%0A  

Remove useless checks