/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.uima.ruta;

import static org.apache.uima.util.Level.SEVERE;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.antlr.runtime.CommonToken;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.uima.UIMAFramework;
import org.apache.uima.UimaContext;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.CASException;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.TypeSystem;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.fit.factory.TypeSystemDescriptionFactory;
import org.apache.uima.fit.internal.ResourceManagerFactory;
import org.apache.uima.resource.ResourceAccessException;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.ResourceManager;
import org.apache.uima.resource.metadata.TypeDescription;
import org.apache.uima.resource.metadata.TypeSystemDescription;
import org.apache.uima.ruta.action.AbstractRutaAction;
import org.apache.uima.ruta.block.RutaBlock;
import org.apache.uima.ruta.condition.AbstractRutaCondition;
import org.apache.uima.ruta.engine.RutaEngine;
import org.apache.uima.ruta.expression.IRutaExpression;
import org.apache.uima.ruta.expression.annotation.IAnnotationExpression;
import org.apache.uima.ruta.expression.bool.IBooleanExpression;
import org.apache.uima.ruta.expression.bool.SimpleBooleanListExpression;
import org.apache.uima.ruta.expression.list.ListExpression;
import org.apache.uima.ruta.expression.number.INumberExpression;
import org.apache.uima.ruta.expression.number.SimpleNumberListExpression;
import org.apache.uima.ruta.expression.resource.LiteralWordListExpression;
import org.apache.uima.ruta.expression.resource.LiteralWordTableExpression;
import org.apache.uima.ruta.expression.resource.StringWordListExpression;
import org.apache.uima.ruta.expression.resource.StringWordTableExpression;
import org.apache.uima.ruta.expression.resource.WordListExpression;
import org.apache.uima.ruta.expression.resource.WordTableExpression;
import org.apache.uima.ruta.expression.string.IStringExpression;
import org.apache.uima.ruta.expression.string.SimpleStringListExpression;
import org.apache.uima.ruta.expression.type.ITypeExpression;
import org.apache.uima.ruta.expression.type.SimpleTypeExpression;
import org.apache.uima.ruta.expression.type.SimpleTypeListExpression;
import org.apache.uima.ruta.resource.CSVTable;
import org.apache.uima.ruta.resource.MultiTreeWordList;
import org.apache.uima.ruta.resource.RutaResourceLoader;
import org.apache.uima.ruta.resource.RutaTable;
import org.apache.uima.ruta.resource.RutaWordList;
import org.apache.uima.ruta.resource.TreeWordList;
import org.apache.uima.ruta.rule.MatchContext;
import org.apache.uima.ruta.rule.RuleElement;
import org.apache.uima.ruta.rule.RuleMatch;
import org.apache.uima.ruta.verbalize.RutaVerbalizer;
import org.apache.uima.util.InvalidXMLException;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

public class RutaEnvironment {

  private static final String DOCUMENT = "Document";

  private final Object annotationTypeDummy = new Object();

  private Map<String, Type> types;

  private Map<String, RutaWordList> wordLists;

  private Map<String, RutaTable> tables;

  private RutaBlock owner;

  /**
   * Mapping from short type name (e.g. {@code W}) to their disambiguated long type names (e.g.
   * {@code org.apache.uima.ruta.type.W}).
   */
  private Map<String, String> namespaces;

  /**
   * Mapping from ambiguous short type names to all their possible long type names.
   */
  private Map<String, Set<String>> ambiguousTypeAlias;

  /**
   * Set of imported typesystems.
   */
  private Set<String> typesystems;

  /**
   * Set of imported scripts.
   */
  private Set<String> scripts;

  /**
   * An alias from a long to a short name.
   */
  private static class Alias {
    final String longName;

    final String shortName;

    Alias(String longName, String shortName) {
      this.longName = longName;
      this.shortName = shortName;
    }
  }

  /**
   * Types that are imported in the environment. Keys are type system descriptors and values are
   * aliased types.
   */
  private Map<String, List<Alias>> typeImports;

  /**
   * Packages that are imported in the environment without a typesystem specification.
   *
   * Keys are package names and values are aliases. An empty string as alias means that all types
   * from the package should be imported in the default namespace.
   */
  private Map<String, List<String>> packageImports;

  /**
   * Set of types that are declared in the script.
   */
  private Set<String> declaredAnnotationTypes;

  private Map<String, Object> variableValues;

  private Map<String, Object> tempVariableValues;

  private Map<String, Class<?>> variableTypes;

  private Map<String, Class<?>> availableTypes;

  private Map<String, Class<?>> variableGenericTypes;

  private Map<String, Class<?>> availableListTypes;

  private Map<String, Triple<Map<String, String>, List<AbstractRutaCondition>, Set<String>>> macroConditions;

  private Map<String, Triple<Map<String, String>, List<AbstractRutaAction>, Set<String>>> macroActions;

  private String[] resourcePaths = null;

  private CAS cas;

  private Map<String, Object> initializedVariables;

  private ResourceManager resourceManager;

  private Map<String, String> variableAliases;

  private RutaVerbalizer verbalizer = new RutaVerbalizer();

  public RutaEnvironment(RutaBlock owner) {
    super();
    this.owner = owner;

    types = new HashMap<>();
    namespaces = new HashMap<>();
    ambiguousTypeAlias = new HashMap<>();
    typesystems = new HashSet<>();
    scripts = new HashSet<>();
    typeImports = new HashMap<>();
    packageImports = new HashMap<>();
    declaredAnnotationTypes = new HashSet<>();
    wordLists = new HashMap<>();
    tables = new HashMap<>();
    variableValues = new HashMap<>();
    tempVariableValues = new HashMap<>();
    variableTypes = new HashMap<>();
    variableGenericTypes = new HashMap<>();
    macroConditions = new HashMap<>();
    macroActions = new HashMap<>();
    availableTypes = new HashMap<>();
    availableTypes.put(RutaConstants.RUTA_VARIABLE_ANNOTATION, AnnotationFS.class);
    availableTypes.put("INT", Integer.class);
    availableTypes.put("STRING", String.class);
    availableTypes.put("DOUBLE", Double.class);
    availableTypes.put("FLOAT", Float.class);
    availableTypes.put("BOOLEAN", Boolean.class);
    availableTypes.put("TYPE", Type.class);
    availableTypes.put("CONDITION", AbstractRutaCondition.class);
    availableTypes.put("ACTION", AbstractRutaAction.class);
    availableTypes.put("WORDLIST", RutaWordList.class);
    availableTypes.put("WORDTABLE", RutaTable.class);
    availableTypes.put(RutaConstants.RUTA_VARIABLE_ANNOTATION_LIST, List.class);
    availableTypes.put("BOOLEANLIST", List.class);
    availableTypes.put("INTLIST", List.class);
    availableTypes.put("DOUBLELIST", List.class);
    availableTypes.put("FLOATLIST", List.class);
    availableTypes.put("STRINGLIST", List.class);
    availableTypes.put(RutaConstants.RUTA_VARIABLE_TYPE_LIST, List.class);
    availableListTypes = new HashMap<>();
    availableListTypes.put(RutaConstants.RUTA_VARIABLE_ANNOTATION_LIST, AnnotationFS.class);
    availableListTypes.put("BOOLEANLIST", Boolean.class);
    availableListTypes.put("INTLIST", Integer.class);
    availableListTypes.put("DOUBLELIST", Double.class);
    availableListTypes.put("FLOATLIST", Float.class);
    availableListTypes.put("STRINGLIST", String.class);
    availableListTypes.put(RutaConstants.RUTA_VARIABLE_TYPE_LIST, Type.class);
    resourcePaths = getResourcePaths();
    initializedVariables = new HashMap<>();
    variableAliases = new HashMap<>();

    // Always import BasicTypeSystem
    addTypeSystem("org.apache.uima.ruta.engine.BasicTypeSystem");
  }

  /**
   * Import short type names.
   *
   * @param cas
   *          Cas to initialize the types for.
   * @param strictImport
   *          Specify whether all types should be imported (false) or only types
   */
  public void initializeTypes(CAS cas, boolean strictImport) {
    this.cas = cas;
    try {
      if (strictImport) {
        importDeclaredTypes(cas.getTypeSystem());
        importDeclaredTypesystems(cas.getTypeSystem());
        importTypeAliases(cas.getTypeSystem());
        importPackageAliases(cas.getTypeSystem());
        importDeclaredScripts(cas.getTypeSystem());
      } else {
        // import all types known to the cas
        importAllTypes(cas.getTypeSystem());
        importTypeAliases(cas.getTypeSystem());
        importPackageAliases(cas.getTypeSystem());
      }

      ambiguousTypeAlias.remove(DOCUMENT);
      namespaces.remove(DOCUMENT);
      Type documentType = cas.getTypeSystem().getType(CAS.TYPE_NAME_DOCUMENT_ANNOTATION);
      addType(DOCUMENT, documentType);
      addType(documentType.getShortName(), documentType);

      Type annotationType = cas.getJCas().getCasType(org.apache.uima.jcas.tcas.Annotation.type);
      addType("Annotation", annotationType);
    } catch (CASException e) {
      UIMAFramework.getLogger(getClass()).log(SEVERE, "Cannot initialize types.", e);
    } catch (InvalidXMLException e) {
      UIMAFramework.getLogger(getClass()).log(SEVERE, "Cannot initialize types.", e);
    }

  }

  /**
   * Imports all types that are known to a type system.
   *
   * @param ts
   *          Type system to import.
   * @throws CASException
   */
  private void importAllTypes(TypeSystem ts) throws CASException {
    Type topType = ts.getTopType();
    if (topType != null) {
      List<Type> list = ts.getProperlySubsumedTypes(topType);
      for (Type type : list) {
        addType(type);
      }
    }
  }

  /**
   * Import all types that are declared by the script.
   *
   * @param casTS
   *          Type system containing all known types.
   * @throws InvalidXMLException
   *           When import cannot be resolved.
   */
  private void importDeclaredTypes(TypeSystem casTS) throws InvalidXMLException {
    for (String name : declaredAnnotationTypes) {
      Type type = casTS.getType(name);
      if (type != null) {
        addType(type);
      } else {
        throw new RuntimeException("Type '" + name + "' not found");
      }
    }
  }

  /**
   * Import all typesystems that are imported in the script.
   *
   * @param casTS
   *          Type system containing all known types.
   * @throws InvalidXMLException
   *           When import cannot be resolved.
   */
  private void importDeclaredTypesystems(TypeSystem casTS) throws InvalidXMLException {
    String[] descriptors = typesystems.toArray(new String[typesystems.size()]);
    TypeSystemDescription ts = TypeSystemDescriptionFactory
            .createTypeSystemDescription(descriptors);
    ts.resolveImports(getResourceManager());
    for (TypeDescription td : ts.getTypes()) {
      Type type = casTS.getType(td.getName());
      if (type != null) {
        addType(type);
      } else {
        throw new RuntimeException("Type '" + td.getName() + "' not found");
      }
    }
  }

  /**
   * Import all already initialized types of imported scripts.
   *
   * @param casTS
   *          Type system containing all known types.
   * @throws InvalidXMLException
   *           When import cannot be resolved.
   */
  private void importDeclaredScripts(TypeSystem casTS) throws InvalidXMLException {

    RutaModule script = owner.getScript();
    for (String eachImportedScript : scripts) {
      RutaModule importedModule = script.getScript(eachImportedScript);
      RutaEnvironment importedEnvironment = importedModule.getRootBlock().getEnvironment();
      Map<String, Type> importedTypeMap = importedEnvironment.getTypes();
      Map<String, String> importedNamespaces = importedEnvironment.getNamespaces();
      Set<Entry<String, String>> entrySet = importedNamespaces.entrySet();
      for (Entry<String, String> entry : entrySet) {
        if (!ownsType(entry.getValue()) && !StringUtils.equals(entry.getKey(), DOCUMENT)) {
          Type type = importedTypeMap.get(entry.getValue());
          addType(entry.getKey(), type);
        }
      }
      // TODO import also wordlists and variables?
    }
  }

  /**
   * Imports all type aliases.
   *
   * @param casTS
   *          Cas type system.
   */
  private void importTypeAliases(TypeSystem casTS) {
    for (List<Alias> aliases : typeImports.values()) {
      for (Alias alias : aliases) {
        Type type = casTS.getType(alias.longName);
        if (type == null) {
          throw new RuntimeException("Type '" + alias.longName + "' not found");
        }
        addType(alias.shortName, casTS.getType(alias.longName));
      }
    }
  }

  /**
   * Import all packages that are imported by the script.
   *
   * @param casTS
   *          Type system containing all known types.
   */
  private void importPackageAliases(TypeSystem casTS) {
    Iterator<Type> iter = casTS.getTypeIterator();
    while (iter.hasNext()) {
      Type type = iter.next();
      String name = type.getName();
      String pkg = name.substring(0, Math.max(name.lastIndexOf('.'), 0));
      List<String> aliases = packageImports.get(pkg);
      if (aliases != null) {
        for (String alias : aliases) {
          if (alias.isEmpty()) {
            addType(type);
          } else {
            addType(alias + "." + type.getShortName(), type);
          }
        }
      }
    }
  }

  public String[] getResourcePaths() {
    if (resourcePaths == null) {
      RutaBlock parent = owner.getParent();
      if (parent != null) {
        return parent.getEnvironment().getResourcePaths();
      }
    }
    return resourcePaths;
  }

  public void setResourcePaths(String[] resourcePaths) {
    this.resourcePaths = resourcePaths;
  }

  public boolean ownsType(String match) {
    match = expand(match);
    return types.keySet().contains(match);
  }

  private String expand(String string) {
    String complete = namespaces.get(string);
    if (complete == null) {
      if (!string.contains(".")) {
        complete = namespaces.get(string);
        if (complete == null) {
          complete = string;
        }
      } else {
        complete = string;
      }
    }
    return complete;
  }

  /**
   * Resolves an annotation type.
   *
   * @param match
   *          Annotation type to resolve.
   * @return Resolved annotation type or null if match is unknown.
   * @throws IllegalArgumentException
   *           When {@code match} is ambiguous.
   */
  public Type getType(String match) {
    // make sure that match is not ambiguous
    Set<String> ambiguousTargets = ambiguousTypeAlias.get(match);
    if (ambiguousTargets != null) {
      StringBuilder message = new StringBuilder(match);
      message.append(" is ambiguous, use one of the following instead : ");
      for (String target : ambiguousTargets) {
        message.append(target).append(' ');
      }
      throw new IllegalArgumentException(message.toString());
    }

    // try to resolve match
    String expanded = expand(match);
    Type type = types.get(expanded);
    if (type == null) {
      RutaBlock parent = owner.getParent();
      if (parent != null) {
        type = parent.getEnvironment().getType(match);
      }
    }
    return type;
  }

  public void addType(String string, Type type) {
    importType(type.getName(), string);
    types.put(type.getName(), type);
  }

  public void addType(Type type) {
    addType(type.getShortName(), type);
  }

  public void declareType(String name) {
    declaredAnnotationTypes.add(name);
  }

  /**
   * Add a typesystem to the script.
   *
   * @param descriptor
   *          Type system's descriptor path.
   */
  public void addTypeSystem(String descriptor) {
    typesystems.add(descriptor);
  }

  /**
   * Add a script to the script.
   *
   * @param script
   *          the script's full name.
   */
  public void addScript(String script) {
    scripts.add(script);
  }

  /**
   * Import a type in the current namespace.
   *
   * @param longName
   *          Complete type name.
   * @param shortName
   *          Short type name (without namespace).
   */
  private void importType(String longName, String shortName) {
    Set<String> targets = ambiguousTypeAlias.get(shortName);
    if (targets != null) {
      // shortName is already ambiguous, add longName to its list of
      // possible targets
      targets.add(longName);
    } else {
      String existing = namespaces.put(shortName, longName);

      if (existing != null && !existing.equals(longName)) {
        // shortName can now be resolved to "existing" or "longName"
        targets = new HashSet<>(2);
        targets.add(existing);
        targets.add(longName);

        // add existing mapping and longName to its list of possible
        // targets
        ambiguousTypeAlias.put(shortName, targets);

        // remove shortName from the namespace because it is ambiguous
        namespaces.remove(shortName);
      }
    }
  }

  /**
   * Import a type from a type system.
   *
   * @param typesystem
   *          Typesystem from which to import the type or null.
   * @param longName
   *          Type to import.
   * @param shortName
   *          Short name to use for this type.
   */
  public void importTypeFromTypeSystem(String typesystem, String longName, String shortName) {
    String key = typesystem != null ? typesystem : "";
    List<Alias> aliases = typeImports.get(key);

    if (aliases == null) {
      aliases = new ArrayList<>();
      typeImports.put(key, aliases);
    }

    aliases.add(new Alias(longName, shortName));
  }

  /**
   * Import a type from a type system.
   *
   * The type is aliased by its unqualified name.
   *
   * @param typesystem
   *          Typesystem from which to import the type or null.
   * @param longName
   *          Type to import.
   */
  public void importTypeFromTypeSystem(String typesystem, String longName) {
    importTypeFromTypeSystem(typesystem, longName,
            longName.substring(longName.lastIndexOf('.') + 1));
  }

  /**
   * Import all the types from a package.
   *
   * @param typesystem
   *          Type system describing the package to load.
   * @param packageName
   *          Package to load or null to load all packages.
   * @param alias
   *          Alias of the package. Null or empty string to use no alias.
   */
  public void importPackageFromTypeSystem(String typesystem, String packageName, String alias) {
    TypeSystemDescription tsd = TypeSystemDescriptionFactory
            .createTypeSystemDescription(typesystem);
    try {
      tsd.resolveImports(getResourceManager());
    } catch (InvalidXMLException e) {
      throw new RuntimeException("Cannot resolve imports in " + typesystem, e);
    }

    for (TypeDescription td : tsd.getTypes()) {
      String qname = td.getName();
      if (packageName == null || (qname.startsWith(packageName)
              && qname.indexOf('.', packageName.length() + 1) == -1)) {
        // td is in packageName
        if (alias != null) {
          String shortName = alias + "." + qname.substring(qname.lastIndexOf('.') + 1);
          importTypeFromTypeSystem(typesystem, qname, shortName);
        } else {
          importTypeFromTypeSystem(typesystem, qname);
        }
      }
    }
  }

  /**
   * Imports all the packages from the specified type system.
   *
   * @param typesystem
   *          Typesystem to load.
   * @param alias
   *          Alias for all the packages.
   */
  public void importAllPackagesFromTypeSystem(String typesystem, String alias) {
    importPackageFromTypeSystem(typesystem, null, alias);
  }

  /**
   * Import all the types from a package that are available at runtime.
   *
   * @param packageName
   *          Package to load.
   * @param alias
   *          Alias of the package. Null or empty string to use no alias.
   */
  public void importPackage(String packageName, String alias) {
    List<String> aliases = packageImports.get(packageName);

    if (aliases == null) {
      aliases = new ArrayList<>(1);
      packageImports.put(packageName, aliases);
    }

    aliases.add(alias == null ? "" : alias);
  }

  public RutaWordList getWordList(String list) {

    if (list == null) {
      return null;
    }

    RutaWordList result = wordLists.get(list);
    UimaContext context = owner.getContext();
    Boolean dictRemoveWS = false;
    if (context != null) {
      dictRemoveWS = (Boolean) context.getConfigParameterValue(RutaEngine.PARAM_DICT_REMOVE_WS);
      if (dictRemoveWS == null) {
        dictRemoveWS = false;
      }
    }
    if (result == null) {
      if (list.endsWith("txt") || list.endsWith("twl") || list.endsWith("mtwl")) {
        ResourceLoader resourceLoader = new RutaResourceLoader(getResourcePaths(),
                getResourceManager().getExtensionClassLoader());
        Resource resource = resourceLoader.getResource(list);
        if (resource.exists()) {
          try {
            if (list.endsWith("mtwl")) {
              wordLists.put(list, new MultiTreeWordList(resource));
            } else {
              wordLists.put(list, new TreeWordList(resource, dictRemoveWS));
            }
          } catch (IOException e) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
                    "Error reading word list" + list, e);
          }
        } else {
          Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Can't find " + list + "!");
        }
      } else {
        try {
          RutaWordList rutaList = (RutaWordList) context.getResourceObject(list);
          if (rutaList != null) {
            wordLists.put(list, rutaList);
          } else {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
                    "Can't find external resource list" + list);
          }
        } catch (ResourceAccessException e) {
          Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
                  "Can't find external resource list" + list, e);
        }
      }
    }

    return wordLists.get(list);
  }

  public RutaTable getWordTable(String table) {
    UimaContext context = owner.getContext();

    RutaTable result = tables.get(table);
    if (result == null) {
      if (table.endsWith("csv") || table.endsWith("txt") || table.endsWith("tsv")) {
        ResourceLoader resourceLoader = new RutaResourceLoader(getResourcePaths(),
                getResourceManager().getExtensionClassLoader());
        Resource resource = resourceLoader.getResource(table);
        if (resource.exists()) {
          try {
            tables.put(table, new CSVTable(resource, getCsvSeparator(context)));
          } catch (IOException e) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
                    "Error reading csv table " + table, e);
          }
        } else {
          Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
                  "Can't find " + table + "!");
        }
      } else {
        try {
          RutaTable rutaTable = (RutaTable) context.getResourceObject(table);
          tables.put(table, rutaTable);
        } catch (ResourceAccessException e) {
          Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
                  "Can't find external resource table" + table, e);
        }
      }
    }

    return tables.get(table);
  }

  private String getCsvSeparator(UimaContext context) {
    if (context != null) {
      String cvsSeparator = (String) context
              .getConfigParameterValue(RutaEngine.PARAM_CSV_SEPARATOR);
      if (cvsSeparator != null) {
        return cvsSeparator;
      }
    }
    return CSVTable.DEFAULT_CSV_SEPARATOR;
  }

  private void addVariable(String name, Class<?> type, Class<?> generic) {
    variableTypes.put(name, type);
    if (generic != null) {
      variableGenericTypes.put(name, generic);
    }
    variableValues.put(name, getInitialValue(name, type));
  }

  @SuppressWarnings("unchecked")
  private Object getInitialValue(String name, Class<?> type) {
    Object init = initializedVariables.get(name);
    if (init != null) {
      if (init instanceof List) {
        ArrayList<Object> list = new ArrayList<>();
        list.addAll((Collection<? extends Object>) init);
        return list;
      }
      return init;
    }
    if (Integer.class.equals(type)) {
      return 0;
    } else if (Double.class.equals(type)) {
      return 0d;
    } else if (Float.class.equals(type)) {
      return 0f;
    } else if (String.class.equals(type)) {
      return null;
    } else if (Boolean.class.equals(type)) {
      return false;
    } else if (Type.class.equals(type)) {
      return null;
    } else if (List.class.equals(type)) {
      return new ArrayList<>();
    }
    return null;
  }

  public void addVariable(String name, String type) {
    addVariable(name, availableTypes.get(type), availableListTypes.get(type));
  }

  public void removeVariable(String name) {
    variableTypes.remove(name);
    variableGenericTypes.remove(name);
    variableValues.remove(name);
    tempVariableValues.remove(name);
  }

  public boolean ownsVariable(String name) {
    return variableTypes.containsKey(name);
  }

  public boolean ownsVariableOfType(String name, String type) {
    if (variableAliases.containsKey(name)) {
      name = variableAliases.get(name);
    }
    Class<?> varclass = variableTypes.get(name);
    Class<?> aclass = availableTypes.get(type);
    boolean list = true;
    if (aclass.equals(List.class)) {
      Class<?> vt = variableGenericTypes.get(name);
      Class<?> at = availableListTypes.get(type);
      list = vt != null && vt.equals(at);
    }
    return list && varclass != null && varclass.equals(aclass);
  }

  public boolean isVariable(String name) {
    if (variableAliases.containsKey(name)) {
      name = variableAliases.get(name);
    }
    if (ownsVariable(name)) {
      return true;
    }
    if (owner != null && owner.getParent() != null) {
      return owner.getParent().getEnvironment().isVariable(name);
    }
    return false;
  }

  public boolean isVariableOfType(String name, String type) {
    return ownsVariableOfType(name, type) || (owner.getParent() != null
            && owner.getParent().getEnvironment().isVariableOfType(name, type));
  }

  public Class<?> getVariableType(String name) {
    if (variableAliases.containsKey(name)) {
      name = variableAliases.get(name);
    }
    Class<?> result = variableTypes.get(name);
    if (result != null) {
      return result;
    } else if (owner.getParent() != null) {
      return owner.getParent().getEnvironment().getVariableType(name);
    }
    return null;
  }

  public Class<?> getVariableGenericType(String name) {
    Class<?> result = variableGenericTypes.get(name);
    if (result != null) {
      return result;
    } else if (owner.getParent() != null) {
      return owner.getParent().getEnvironment().getVariableGenericType(name);
    }
    return null;
  }

  public <T> T getVariableValue(String name, Class<T> type, RutaStream stream) {
    if (variableAliases.containsKey(name)) {
      name = variableAliases.get(name);
    }
    Object result = null;
    boolean containsKey = variableValues.containsKey(name);
    result = tempVariableValues.get(name);
    if (result == null) {
      result = variableValues.get(name);
    }

    if (result instanceof String && type.equals(Type.class)) {
      // "cast" string to type, because initial values were set when there
      // was no cas/type system
      // yet
      String stringValue = (String) result;
      result = types.get(stringValue);
      if (result == null) {
        // try to resolve short names
        result = getType(stringValue);
      }
    }

    if (containsKey && result == null) {
      // TODO find the problem with the null values!
      // this might now work for word lists in another env.
      Object initialValue = getInitialValue(name, type);
      if (initialValue instanceof Type) {
        return type.cast(initialValue);
      } else if (initialValue != null) {
        throw new IllegalArgumentException("Variable " + name + " of type " + type
                + " is not correctly initialized! It is not a Type, but " + initialValue);
      }
    }
    if (result == annotationTypeDummy) {
      return type.cast(cas.getAnnotationType());
    }
    if (result != null) {
      MatchContext context = new MatchContext(owner);
      if (RutaWordList.class.isAssignableFrom(type) && result instanceof WordListExpression) {
        WordListExpression wle = (WordListExpression) result;
        RutaWordList list = wle.getList(context, stream);
        return type.cast(list);
      } else if (RutaTable.class.isAssignableFrom(type) && result instanceof WordTableExpression) {
        WordTableExpression wte = (WordTableExpression) result;
        RutaTable table = wte.getTable(context, stream);
        return type.cast(table);
      } else {
        return type.cast(result);
      }
    } else if (owner.getParent() != null) {
      return owner.getParent().getEnvironment().getVariableValue(name, type, stream);
    }
    return null;
  }

  public Object getVariableValue(String name, RutaStream stream) {
    return getVariableValue(name, Object.class, stream);
  }

  @SuppressWarnings("rawtypes")
  public Object getLiteralValue(String var, Object value) {
    if (ownsVariable(var)) {
      MatchContext context = new MatchContext(owner);
      Class<?> clazz = variableTypes.get(var);
      if (value instanceof INumberExpression) {
        INumberExpression ne = (INumberExpression) value;
        if (clazz.equals(Integer.class)) {
          return ne.getIntegerValue(context, null);
        } else if (clazz.equals(Double.class)) {
          return ne.getDoubleValue(context, null);
        } else if (clazz.equals(Float.class)) {
          return ne.getFloatValue(context, null);
        } else if (clazz.equals(String.class)) {
          return ne.getStringValue(context, null);
        }
      } else if (clazz.equals(String.class) && value instanceof IStringExpression) {
        IStringExpression se = (IStringExpression) value;
        return se.getStringValue(context, null);
      } else if (clazz.equals(Boolean.class) && value instanceof IBooleanExpression) {
        IBooleanExpression be = (IBooleanExpression) value;
        return be.getBooleanValue(context, null);
      }
      if (clazz.equals(RutaWordList.class) && value instanceof LiteralWordListExpression) {
        return value;
      } else if (clazz.equals(RutaWordList.class) && value instanceof StringWordListExpression) {
        return value;
      } else if (clazz.equals(RutaWordList.class) && value instanceof String) {
        return value;
      } else if (clazz.equals(RutaTable.class) && value instanceof LiteralWordTableExpression) {
        return value;
      } else if (clazz.equals(RutaTable.class) && value instanceof StringWordTableExpression) {
        return value;
      } else if (clazz.equals(RutaTable.class) && value instanceof String) {
        return value;
      } else if (clazz.equals(List.class) && value instanceof ListExpression) {
        List list = getList((ListExpression) value);
        return list;
      } else if (clazz.equals(Type.class) && value instanceof CommonToken) {
        String typeName = ((CommonToken) value).getText();
        return typeName;
      } else if (clazz.equals(Type.class) && value instanceof SimpleTypeExpression) {
        String typeName = ((SimpleTypeExpression) value).getTypeString();
        return typeName;
      }

      return null;
    } else {
      return owner.getParent().getEnvironment().getLiteralValue(var, value);
    }
  }

  @SuppressWarnings("unchecked")
  public void setInitialVariableValue(String var, Object value) {
    if (ownsVariable(var)) {
      if (value instanceof List) {
        List<Object> initValue = new ArrayList<>();
        initValue.addAll((Collection<? extends Object>) value);
        initializedVariables.put(var, initValue);
      } else {
        initializedVariables.put(var, value);
      }
      setVariableValue(var, value);
    } else if (owner.getParent() != null) {
      owner.getParent().getEnvironment().setInitialVariableValue(var, value);
    }
  }

  public void setVariableValue(String name, Object value) {
    if (variableAliases.containsKey(name)) {
      name = variableAliases.get(name);
    }
    if (ownsVariable(name)) {
      Class<?> clazz = variableTypes.get(name);
      if (value == null) {
        value = getInitialValue(name, clazz);
      }
      variableValues.put(name, value);
    } else if (owner.getParent() != null) {
      owner.getParent().getEnvironment().setVariableValue(name, value);
    }
  }

  public void setTempVariableValue(String name, Object value) {
    if (variableAliases.containsKey(name)) {
      name = variableAliases.get(name);
    }
    tempVariableValues.put(name, value);
  }

  @SuppressWarnings("rawtypes")
  private List getList(ListExpression value) {
    if (value instanceof SimpleBooleanListExpression) {
      SimpleBooleanListExpression e = (SimpleBooleanListExpression) value;
      return e.getList();
    } else if (value instanceof SimpleNumberListExpression) {
      SimpleNumberListExpression e = (SimpleNumberListExpression) value;
      return e.getList();
    } else if (value instanceof SimpleStringListExpression) {
      SimpleStringListExpression e = (SimpleStringListExpression) value;
      return e.getList();
    } else if (value instanceof SimpleTypeListExpression) {
      SimpleTypeListExpression e = (SimpleTypeListExpression) value;
      return e.getList();
    }
    return null;
  }

  public void reset(CAS cas) {
    this.cas = cas;
    Set<Entry<String, Object>> entrySet = variableValues.entrySet();
    for (Entry<String, Object> entry : entrySet) {
      String key = entry.getKey();
      Class<?> variableType = variableTypes.get(key);
      Object initialValue = getInitialValue(key, variableTypes.get(key));
      if ((!variableType.equals(RutaTable.class) && !variableType.equals(RutaWordList.class))
              || initialValue != null) {
        // not for word lists
        entry.setValue(initialValue);
      }
    }
  }

  public ResourceManager getResourceManager() {
    if (resourceManager != null) {
      return resourceManager;
    } else {
      RutaBlock parent = owner.getParent();
      if (parent != null) {
        return parent.getEnvironment().getResourceManager();
      }
    }
    // at least return default resource manager
    try {
      resourceManager = ResourceManagerFactory.newResourceManager();
      return resourceManager;
    } catch (ResourceInitializationException e) {
      UIMAFramework.getLogger(getClass()).log(SEVERE,
              "Failed to initialize fallback ResourceManager.", e);
    }
    return UIMAFramework.newDefaultResourceManager();
  }

  public void setResourceManager(ResourceManager resourceManager) {
    this.resourceManager = resourceManager;
  }

  public void addMacroAction(String name, Map<String, String> def, Set<String> vars,
          List<AbstractRutaAction> actions) {
    macroActions.put(name, new ImmutableTriple<>(def, actions, vars));
  }

  public void addMacroCondition(String name, Map<String, String> def, Set<String> vars,
          List<AbstractRutaCondition> conditions) {
    macroConditions.put(name, new ImmutableTriple<>(def, conditions, vars));
  }

  public boolean isMacroAction(String name) {
    boolean isDefined = macroActions.keySet().contains(name);
    if (isDefined) {
      return true;
    } else if (owner != null && owner.getParent() != null) {
      return owner.getParent().getEnvironment().isMacroAction(name);
    }
    return false;
  }

  public boolean isMacroCondition(String name) {
    boolean isDefined = macroConditions.keySet().contains(name);
    if (isDefined) {
      return true;
    } else if (owner != null && owner.getParent() != null) {
      return owner.getParent().getEnvironment().isMacroCondition(name);
    }
    return false;
  }

  public Triple<Map<String, String>, List<AbstractRutaAction>, Set<String>> getMacroAction(
          String name) {
    Triple<Map<String, String>, List<AbstractRutaAction>, Set<String>> definition = macroActions
            .get(name);
    if (definition != null) {
      return definition;
    } else if (owner != null && owner.getParent() != null) {
      return owner.getParent().getEnvironment().getMacroAction(name);
    }
    return null;
  }

  public Triple<Map<String, String>, List<AbstractRutaCondition>, Set<String>> getMacroCondition(
          String name) {
    Triple<Map<String, String>, List<AbstractRutaCondition>, Set<String>> definition = macroConditions
            .get(name);
    if (definition != null) {
      return definition;
    } else if (owner != null && owner.getParent() != null) {
      return owner.getParent().getEnvironment().getMacroCondition(name);
    }
    return null;
  }

  public void addAliasVariable(String name, String var) {
    variableAliases.put(name, var);
  }

  public void removeAliasVariable(String name) {
    variableAliases.remove(name);
  }

  public String getVariableNameOfExpression(IRutaExpression expression) {
    String verbalize = verbalizer.verbalize(expression);
    return verbalize;
  }

  public Map<String, Type> getTypes() {
    return types;
  }

  public Set<String> getDeclaredAnnotationTypes() {
    return declaredAnnotationTypes;
  }

  public Set<String> getTypesystems() {
    return typesystems;
  }

  public Map<String, String> getNamespaces() {
    return namespaces;
  }

  public void addMatchToVariable(RuleMatch ruleMatch, RuleElement element, MatchContext context,
          RutaStream stream) {
    String var = element.getLabel();
    if (StringUtils.isBlank(var)) {
      return;
    }
    List<AnnotationFS> annotations = ruleMatch.getMatchedAnnotationsOfElement(element);
    addAnnotationsToVariable(annotations, var, context);
  }

  public void removeVariableValue(String var, MatchContext context) {
    if (StringUtils.isBlank(var)) {
      return;
    }
    setTempVariableValue(var, null);
  }

  public void addAnnotationsToVariable(List<AnnotationFS> annotations, String var,
          MatchContext context) {
    if (StringUtils.isBlank(var)) {
      return;
    }

    Class<?> variableType = getVariableType(var);
    if (List.class.equals(variableType) && AnnotationFS.class.equals(getVariableGenericType(var))) {
      setTempVariableValue(var, annotations);
    } else if (AnnotationFS.class.equals(variableType)) {
      if (context.getDirection()) {
        AnnotationFS annotation = null;
        if (annotations != null) {
          if (context.getDirection()) {
            annotation = annotations.get(annotations.size() - 1);
          } else {
            annotation = annotations.get(0);
          }
        }
        setTempVariableValue(var, annotation);
      }
    }
  }

  public void acceptTempVariableValues(Collection<String> localVariables) {
    for (String variableName : localVariables) {
      if (tempVariableValues.containsKey(variableName)) {
        Object value = tempVariableValues.get(variableName);
        setVariableValue(variableName, value);
      }
    }

    clearTempVariables(localVariables);
  }

  public void clearTempVariables(Collection<String> localVariables) {
    for (String variableName : localVariables) {
      tempVariableValues.remove(variableName);
    }
  }

  public void ensureMaterializedInitialValues(MatchContext matchContext, RutaStream stream) {

    for (Entry<String, Object> entry : new ArrayList<>(initializedVariables.entrySet())) {
      String var = entry.getKey();
      Object value = entry.getValue();

      if (value instanceof IAnnotationExpression || value instanceof IBooleanExpression
              || value instanceof INumberExpression || value instanceof IStringExpression
              || value instanceof ITypeExpression) {
        Class<?> clazz = variableTypes.get(var);
        Object expressionValue = stream.getExpressionValue(clazz, (IRutaExpression) value,
                matchContext);
        initializedVariables.put(var, expressionValue);
        variableValues.put(var, expressionValue);
      } else if (value instanceof List) {
        List<?> list = (List<?>) value;
        List<Object> newList = new ArrayList<>(list.size());
        Class<?> clazz = variableGenericTypes.get(var);
        for (Object each : list) {
          if (each instanceof IAnnotationExpression || each instanceof IBooleanExpression
                  || each instanceof INumberExpression || each instanceof IStringExpression
                  || each instanceof ITypeExpression) {
            Object expressionValue = stream.getExpressionValue(clazz, (IRutaExpression) each,
                    matchContext);
            newList.add(expressionValue);
          } else {
            newList.add(each);
          }
        }
        initializedVariables.put(var, newList);
        variableValues.put(var, new ArrayList<>(newList));
      }
    }
  }
}
