package org.rabix.bindings.protocol.draft2.bean;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.rabix.bindings.protocol.draft2.expression.Draft2ExpressionException;
import org.rabix.bindings.protocol.draft2.expression.helper.Draft2ExpressionBeanHelper;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Draft2CommandLineTool extends Draft2JobApp {

  public static final String KEY_ARGUMENT_VALUE = "valueFrom";

  @JsonProperty("stdin")
  private Object stdin;
  @JsonProperty("stdout")
  private Object stdout;
  @JsonProperty("baseCommand")
  private List<Object> baseCommands;
  @JsonProperty("arguments")
  private List<Object> arguments;
  

  public Draft2CommandLineTool() {
    super();
    this.baseCommands = new ArrayList<>();
    this.arguments = new ArrayList<>();
  }

  public List<Object> getBaseCmd(Draft2Job job) throws Draft2ExpressionException {
    List<Object> result = new LinkedList<>();

    for (Object baseCmd : baseCommands) {
      if (Draft2ExpressionBeanHelper.isExpression(baseCmd)) {
        Object transformed = Draft2ExpressionBeanHelper.evaluate(job, baseCmd);
        if (transformed != null) {
          result.add(transformed);
        }
      } else {
        result.add(baseCmd);
      }
    }
    return result;
  }

  public String getStdin(Draft2Job job) throws Draft2ExpressionException {
    if (Draft2ExpressionBeanHelper.isExpression(stdin)) {
      return Draft2ExpressionBeanHelper.evaluate(job, stdin);
    }
    return stdin != null ? stdin.toString() : "";
  }

  public String getStdout(Draft2Job job) throws Draft2ExpressionException {
    if (Draft2ExpressionBeanHelper.isExpression(stdout)) {
      return Draft2ExpressionBeanHelper.evaluate(job, stdout);
    }
    return stdout != null ? stdout.toString() : "";
  }

  public String getStderr(Draft2Job job) throws Draft2ExpressionException {
    String stdout = getStdout(job);
    return changeExtension(stdout, "err");
  }

  @JsonIgnore
  public boolean hasArguments() {
    return arguments != null;
  }

  public List<Object> getArguments() {
    return arguments;
  }

  @JsonIgnore
  public Object getArgument(Draft2Job job, Object binding) throws Draft2ExpressionException {
    if (binding instanceof Map<?, ?>) {
      Object value = ((Map<?, ?>) binding).get(KEY_ARGUMENT_VALUE);
      if (value == null) {
        return null;
      }
      if (Draft2ExpressionBeanHelper.isExpression(value)) {
        return Draft2ExpressionBeanHelper.evaluate(job, value);
      }
      return value;
    }
    return null;
  }

  /**
   * Replaces extension if there is any
   */
  private String changeExtension(String fileName, String extension) {
    if (fileName == null) {
      return null;
    }
    int lastIndexOf = fileName.lastIndexOf(".");
    return lastIndexOf != -1 ? fileName.substring(0, lastIndexOf + 1) + extension : fileName + "." + extension;
  }

  @Override
  @JsonIgnore
  public Draft2JobAppType getType() {
    return Draft2JobAppType.COMMAND_LINE_TOOL;
  }

  @Override
  public String toString() {
    return "CommandLineTool [stdin=" + stdin + ", stdout=" + stdout + ", baseCommands=" + baseCommands + ", arguments="
        + arguments + ", successCodes=" + successCodes + ", id=" + id + ", context=" + context + ", description="
        + description + ", label=" + label + ", contributor=" + contributor + ", owner=" + owner + ", inputs=" + getInputs()
        + ", outputs=" + getOutputs() + ", requirements=" + requirements + "]";
  }

}

@@ -686,28 +686,22 @@
 private 
-List%3C
 Object
-%3E
  baseCom
@@ -704,17 +704,16 @@
 eCommand
-s
 ;%0A  @Jso
@@ -841,17 +841,16 @@
 eCommand
-s
  = new A
@@ -904,24 +904,57 @@
 t%3C%3E();%0A  %7D%0A%0A
+  @SuppressWarnings(%22unchecked%22)%0A
   public Lis
@@ -1071,16 +1071,60 @@
 t%3C%3E();%0A%0A
+    if (baseCommand instanceof List%3C?%3E) %7B%0A  
     for 
@@ -1140,16 +1140,32 @@
 aseCmd :
+ ((List%3CObject%3E)
  baseCom
@@ -1168,17 +1168,17 @@
 eCommand
-s
+)
 ) %7B%0A    
@@ -1183,60 +1183,199 @@
     
-if (Draft2ExpressionBeanHelper.isExpression(baseCmd)
+  Object transformed = transformBaseCommand(job, baseCmd);%0A        if (transformed != null) %7B%0A          result.add(transformed);%0A        %7D%0A      %7D%0A    %7D else if (baseCommand instanceof String
 ) %7B%0A
@@ -1372,34 +1372,32 @@
 String) %7B%0A      
-  
 Object transform
@@ -1405,43 +1405,28 @@
 d = 
-Draft2ExpressionBeanHelper.evaluate
+transformBaseCommand
 (job
@@ -1424,33 +1424,37 @@
 mmand(job, baseC
-m
+omman
 d);%0A        if (
@@ -1439,34 +1439,32 @@
 Command);%0A      
-  
 if (transformed 
@@ -1466,34 +1466,32 @@
 rmed != null) %7B%0A
-  
         result.a
@@ -1503,32 +1503,36 @@
 ansformed);%0A    
+  %7D%0A
     %7D%0A      %7D el
@@ -1529,80 +1529,314 @@
     
-  %7D else %7B%0A        result.add(baseCmd);%0A      %7D%0A    %7D%0A    return result;
+return result;%0A  %7D%0A  %0A  private Object transformBaseCommand(Draft2Job job, Object baseCommand) throws Draft2ExpressionException %7B%0A    if (Draft2ExpressionBeanHelper.isExpression(baseCommand)) %7B%0A      return Draft2ExpressionBeanHelper.evaluate(job, baseCommand);%0A    %7D else %7B%0A      return baseCommand;%0A    %7D
 %0A  %7D
@@ -3714,17 +3714,16 @@
 eCommand
-s
  + %22, ar

fix base commands