package com.hubspot.jinjava.el.ext;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import javax.el.ELContext;

import com.hubspot.jinjava.objects.collections.PyMap;

import de.odysseus.el.tree.Bindings;
import de.odysseus.el.tree.impl.ast.AstIdentifier;
import de.odysseus.el.tree.impl.ast.AstLiteral;
import de.odysseus.el.tree.impl.ast.AstNode;
import de.odysseus.el.tree.impl.ast.AstString;

public class AstDict extends AstLiteral {

  private final Map<AstNode, AstNode> dict;

  public AstDict(Map<AstNode, AstNode> dict) {
    this.dict = dict;
  }

  @Override
  public Object eval(Bindings bindings, ELContext context) {
    Map<String, Object> resolved = new HashMap<>();

    for (Map.Entry<AstNode, AstNode> entry : dict.entrySet()) {
      String key;

      if (entry.getKey() instanceof AstString) {
        key = Objects.toString(entry.getKey().eval(bindings, context));
      } else if (entry.getKey() instanceof AstIdentifier) {
        key = ((AstIdentifier) entry.getKey()).getName();
      } else {
        throw new IllegalArgumentException("Dict key must be a string or identifier, was: " + entry.getKey());
      }

      resolved.put(key, entry.getValue().eval(bindings, context));
    }

    return new PyMap(resolved);
  }

  @Override
  public void appendStructure(StringBuilder builder, Bindings bindings) {
    throw new UnsupportedOperationException("TODO");
  }

  @Override
  public String toString() {
    StringBuilder s = new StringBuilder("{");

    for (Map.Entry<AstNode, AstNode> entry : dict.entrySet()) {
      s.append(Objects.toString(entry.getKey())).append(":").append(Objects.toString(entry.getValue()));
    }

    return s.append("}").toString();
  }

}

@@ -129,24 +129,85 @@
 ELContext;%0A%0A
+import com.hubspot.jinjava.interpret.TemplateStateException;%0A
 import com.h
@@ -1125,23 +1125,21 @@
 new 
-IllegalArgument
+TemplateState
 Exce

throw template state exception for invalid dict key