/*
 * 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.rule;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.FSIterator;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.ruta.RutaEnvironment;
import org.apache.uima.ruta.RutaStream;
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.AnnotationTypeExpression;
import org.apache.uima.ruta.expression.string.IStringExpression;
import org.apache.uima.ruta.type.RutaBasic;
import org.apache.uima.ruta.visitor.InferenceCrowd;

public class WildCardRuleElement extends AbstractRuleElement {

  public WildCardRuleElement(List<AbstractRutaCondition> conditions,
          List<AbstractRutaAction> actions, RuleElementContainer container, RutaBlock parent) {
    super(null, conditions, actions, container, parent);
  }

  @Override
  public List<RuleMatch> startMatch(RuleMatch ruleMatch, RuleApply ruleApply,
          ComposedRuleElementMatch containerMatch, RuleElement entryPoint, RutaStream stream,
          InferenceCrowd crowd) {
    List<RuleMatch> result = continueMatch(true, null, ruleMatch, ruleApply, containerMatch, null,
            entryPoint, stream, crowd);
    return result;
  }

  @Override
  public List<RuleMatch> continueMatch(boolean after, AnnotationFS annotation, RuleMatch ruleMatch,
          RuleApply ruleApply, ComposedRuleElementMatch containerMatch, RuleElement sideStepOrigin,
          RuleElement entryPoint, RutaStream stream, InferenceCrowd crowd) {
    Pair<RuleElement, Integer> next = getNextRuleElement(after, this);
    RuleElement nextElement = next.getLeft();
    int nextDepth = next.getRight().intValue();
    List<RuleMatch> result = tryWithNextRuleElement(nextElement, after, annotation, ruleMatch,
            ruleApply, containerMatch, nextDepth, sideStepOrigin, entryPoint, stream, crowd);
    return result;
  }

  private Pair<RuleElement, Integer> getNextRuleElement(boolean after, RuleElement element) {
    RuleElement nextElement = null;
    RuleElement current = element;
    int nextDepth = -1;
    while (nextElement == null && current != null && current.getContainer() != null) {
      RuleElementContainer container = current.getContainer();
      nextElement = container.getNextElement(after, current);
      if (container instanceof RuleElement) {
        current = (RuleElement) container;
        nextDepth++;
      } else {
        break;
      }
    }
    if (nextElement == null) {
      nextDepth = 0;
    }
    return new ImmutablePair<>(nextElement, Integer.valueOf(nextDepth));
  }

  private List<RuleMatch> tryWithNextRuleElement(RuleElement nextElement, boolean after,
          AnnotationFS annotation, RuleMatch ruleMatch, RuleApply ruleApply,
          ComposedRuleElementMatch containerMatch, int nextDepth, RuleElement sideStepOrigin,
          RuleElement entryPoint, RutaStream stream, InferenceCrowd crowd) {
    List<RuleMatch> result = new ArrayList<>();
    // what is the next stuff that should match?
    if (nextElement == null) {
      AnnotationFS afs = getCoveredByWildCard(after, annotation, null, stream);
      doMatch(after, afs, ruleMatch, containerMatch, annotation == null, stream, crowd);
      ComposedRuleElement composed = (ComposedRuleElement) getContainer();
      // [Peter] was ruleMatch.matched(), but it did not fail when matches?!
      result = composed.fallbackContinue(after, !ruleMatch.matched(), afs, ruleMatch, ruleApply,
              containerMatch, sideStepOrigin, entryPoint, stream, crowd);
    } else if (nextElement instanceof RutaRuleElement) {
      RutaRuleElement re = (RutaRuleElement) nextElement;
      RutaMatcher matcher = re.getMatcher();
      if (matcher instanceof RutaAnnotationTypeMatcher) {
        result = tryWithNextAnnotationType(after, annotation, nextElement, null, ruleMatch,
                ruleApply, containerMatch, nextDepth, sideStepOrigin, entryPoint, stream, crowd);
      } else if (matcher instanceof RutaLiteralMatcher) {
        result = tryWithNextLiteral(after, annotation, re, ruleMatch, ruleApply, containerMatch,
                nextDepth, sideStepOrigin, stream, crowd);
      }
    } else if (nextElement instanceof ComposedRuleElement) {
      ComposedRuleElement cre = ((ComposedRuleElement) nextElement);
      result = tryWithNextComposed(after, annotation, cre, ruleMatch, ruleApply, containerMatch,
              nextDepth, sideStepOrigin, stream, crowd);
    } else if (nextElement instanceof WildCardRuleElement) {
      // another wildcard? seriously? then just assume its an "Annotation" type
      CAS cas = stream.getCas();
      result = tryWithNextAnnotationType(after, annotation, nextElement, cas.getAnnotationType(),
              ruleMatch, ruleApply, containerMatch, nextDepth, sideStepOrigin, entryPoint, stream,
              crowd);
    }
    return result;
  }

  private List<RuleMatch> tryWithNextComposed(boolean after, AnnotationFS annotation,
          ComposedRuleElement cre, RuleMatch ruleMatch, RuleApply ruleApply,
          ComposedRuleElementMatch containerMatch, int nextDepth, RuleElement sideStepOrigin,
          RutaStream stream, InferenceCrowd crowd) {
    List<RuleMatch> result = new ArrayList<>();
    AnnotationFS nextOne = annotation;
    boolean doneHere = false;
    while (!doneHere
            && (nextOne = getNextPositionForComposed(cre, after, nextOne, stream)) != null) {
      int pointer = after ? nextOne.getBegin() : nextOne.getEnd();
      RutaBasic anchor = stream.getAnchor(!after, pointer);
      ComposedRuleElementMatch extendedContainerMatch = containerMatch.copy();
      RuleMatch extendedMatch = ruleMatch.copy(extendedContainerMatch, after);
      AnnotationFS coveredByWildCard = getCoveredByWildCard(after, annotation, nextOne, stream);
      doMatch(after, coveredByWildCard, extendedMatch, extendedContainerMatch, annotation == null,
              stream, crowd);
      doMatchPotentialParentElements(after, annotation, nextDepth, extendedMatch,
              extendedContainerMatch, coveredByWildCard, stream, crowd);
      if (extendedMatch.matched()) {
        ComposedRuleElementMatch nextContainerMatch = getContainerMatchOfNextElement(
                extendedContainerMatch, nextDepth);
        // Hotfix for UIMA-3002
        int applied = ruleApply.getApplied();
        if (anchor == null) {
          result = cre.startMatch(extendedMatch, ruleApply, nextContainerMatch, cre, stream, crowd);
        } else {
          result = cre.continueMatch(after, anchor, extendedMatch, ruleApply, nextContainerMatch,
                  sideStepOrigin, cre, stream, crowd);
        }
        List<RuleElementMatch> nextList = nextContainerMatch.getInnerMatches().get(cre);
        boolean matched = hasMatched(nextList);
        if (!matched) {
          // Hotfix for UIMA-3002
          if (ruleApply.getApplied() > applied) {
            doneHere = true;
          }
          // end hotfix
          nextOne = stream.getAnchor(after, getNextPointer(!after, nextOne));
        } else {
          doneHere = true;
        }
      } else {
        // conditions of wildcard element did not match, try the next possible anchor for the
        // next rule element
        nextOne = annotation;
      }
    }
    if (!doneHere) {
      ComposedRuleElementMatch nextContainerMatch = getContainerMatchOfNextElement(containerMatch,
              nextDepth);
      result = cre.continueMatch(after, annotation, ruleMatch, ruleApply, nextContainerMatch,
              sideStepOrigin, null, stream, crowd);
    }
    return result;
  }

  private boolean hasMatched(List<RuleElementMatch> nextList) {
    if (nextList == null || nextList.isEmpty()) {
      return false;
    }
    boolean result = true;
    for (RuleElementMatch each : nextList) {
      result &= each.matched();
    }
    return result;
  }

  private AnnotationFS getNextPositionForComposed(ComposedRuleElement cre, boolean after,
          AnnotationFS annotation, RutaStream stream) {
    RuleElement element = getNextAtomicRuleElement(cre, after);
    AnnotationFS result = null;
    Boolean conjunct = cre.getConjunct();
    if (element instanceof WildCardRuleElement) {
      if (after) {
        return stream.getAnchor(after, annotation.getEnd());
      } else {
        return stream.getAnchor(after, annotation.getBegin());
      }
    } else if (conjunct != null && !conjunct) {
      // disjunctive
      List<RuleElement> ruleElements = cre.getRuleElements();
      List<AnnotationFS> nextPostions = new ArrayList<>();
      for (RuleElement ruleElement : ruleElements) {
        if (ruleElement instanceof ComposedRuleElement) {
          AnnotationFS nextPositionForComposed = getNextPositionForComposed(
                  (ComposedRuleElement) ruleElement, after, annotation, stream);
          if (nextPositionForComposed != null) {
            nextPostions.add(nextPositionForComposed);
          }
        } else if (ruleElement instanceof RutaRuleElement) {
          AnnotationFS nextPositionForAtomic = getNextPositionForAtomic(after, annotation, stream,
                  ruleElement, result);
          if (nextPositionForAtomic != null) {
            nextPostions.add(nextPositionForAtomic);
          }
        }
      }
      if (!nextPostions.isEmpty()) {

        Collections.sort(nextPostions, new AnnotationComparator());
        if (after) {
          result = nextPostions.get(0);
        } else {
          result = nextPostions.get(nextPostions.size() - 1);
        }
      }
    } else {
      result = getNextPositionForAtomic(after, annotation, stream, element, result);
    }

    return result;
  }

  private AnnotationFS getNextPositionForAtomic(boolean after, AnnotationFS annotation,
          RutaStream stream, RuleElement element, AnnotationFS result) {
    RutaRuleElement re = (RutaRuleElement) element;
    RutaMatcher matcher = re.getMatcher();

    if (matcher instanceof RutaLiteralMatcher) {
      RutaLiteralMatcher lm = (RutaLiteralMatcher) matcher;
      IStringExpression expression = lm.getExpression();
      MatchContext context = new MatchContext(this, null, after);
      String stringValue = expression.getStringValue(context, stream);
      AnnotationFS documentAnnotation = stream.getDocumentAnnotation();
      int delta = documentAnnotation.getBegin();
      String document = documentAnnotation.getCoveredText();
      int pointer = annotation.getEnd() - delta;
      int indexOf = document.indexOf(stringValue, pointer);
      if (indexOf < 0) {
        return null;
      } else {
        return stream.getAnchor(after, indexOf);
      }
    } else {
      FSIterator<AnnotationFS> iterator = getIterator(after, annotation, re, null, stream);
      if (iterator == null) {
        return null;
      }

      if (iterator.isValid()) {
        result = iterator.get();
        if (annotation != null && (after && result.getEnd() == annotation.getEnd())
                || (!after && result.getBegin() == annotation.getBegin())) {
          moveOn(after, iterator, stream);
          if (iterator.isValid()) {
            result = iterator.get();
          } else {
            result = null;
          }
        }

      }
    }
    return result;
  }

  private RuleElement getNextAtomicRuleElement(ComposedRuleElement cre, boolean after) {
    if (after) {
      RuleElement firstElement = cre.getFirstElement();
      if (firstElement instanceof ComposedRuleElement) {
        return getNextAtomicRuleElement((ComposedRuleElement) firstElement, after);
      } else {
        return firstElement;
      }
    } else {
      RuleElement lastElement = cre.getLastElement();
      if (lastElement instanceof ComposedRuleElement) {
        return getNextAtomicRuleElement((ComposedRuleElement) lastElement, after);
      } else {
        return lastElement;
      }
    }
  }

  private List<RuleMatch> tryWithNextAnnotationType(boolean after, AnnotationFS annotation,
          RuleElement nextElement, Type defaultType, RuleMatch ruleMatch, RuleApply ruleApply,
          ComposedRuleElementMatch containerMatch, int nextDepth, RuleElement sideStepOrigin,
          RuleElement entryPoint, RutaStream stream, InferenceCrowd crowd) {
    List<RuleMatch> result = new ArrayList<>();
    FSIterator<AnnotationFS> iterator = getIterator(after, annotation, nextElement, defaultType,
            stream);
    // already matched something maybe, but now at the end of the document
    if (iterator == null || !iterator.isValid()) {
      RuleElementContainer c = getContainer();
      if (c instanceof ComposedRuleElement) {
        ComposedRuleElement cre = (ComposedRuleElement) c;

        MatchContext context = new MatchContext(this, null, after);
        if (nextElement.getQuantifier().isOptional(context, stream)) {
          // optional did not match -> match complete window/document
          // TODO refactor

          AnnotationFS nextAnchor = getNextAnchor(after, annotation, nextElement, ruleMatch,
                  containerMatch, sideStepOrigin, stream, crowd);

          AnnotationFS coveredByWildCard = getCoveredByWildCard(after, annotation, nextAnchor,
                  stream);
          doMatch(after, coveredByWildCard, ruleMatch, containerMatch, annotation == null, stream,
                  crowd);
          if (ruleMatch.matched()) {
            ComposedRuleElementMatch nextContainerMatch = getContainerMatchOfNextElement(
                    containerMatch, nextDepth);
            if (coveredByWildCard == null) {
              result = nextElement.startMatch(ruleMatch, ruleApply, nextContainerMatch, nextElement,
                      stream, crowd);
            } else {
              // TODO match and containermatch should be on the correct level!
              result = nextElement.continueMatch(after, coveredByWildCard, ruleMatch, ruleApply,
                      nextContainerMatch, sideStepOrigin, nextElement, stream, crowd);
            }
          } else {
            result = cre.fallbackContinue(after, true, annotation, ruleMatch, ruleApply,
                    containerMatch, sideStepOrigin, entryPoint, stream, crowd);
          }
        } else {

          if (ruleApply == null && entryPoint != null && entryPoint.equals(nextElement)) {
            return result;
          } else {
            result = cre.fallbackContinue(after, true, annotation, ruleMatch, ruleApply,
                    containerMatch, sideStepOrigin, entryPoint, stream, crowd);
          }
        }
      }
      return result;
    }
    if (iterator.isValid() && !stream.isVisible(iterator.get())) {
      moveOn(after, iterator, stream);
    }
    boolean doneHere = false;
    while (!doneHere && iterator.isValid() && stream.isVisible(iterator.get())) {
      AnnotationFS nextOne = iterator.get();
      int pointer = after ? nextOne.getBegin() : nextOne.getEnd();
      AnnotationFS anchor = stream.getAnchor(!after, pointer);

      ComposedRuleElementMatch extendedContainerMatch = containerMatch.copy();
      RuleMatch extendedMatch = ruleMatch.copy(extendedContainerMatch, after);

      AnnotationFS coveredByWildCard = getCoveredByWildCard(after, annotation, nextOne, stream);
      doMatch(after, coveredByWildCard, extendedMatch, extendedContainerMatch, annotation == null,
              stream, crowd);

      doMatchPotentialParentElements(after, annotation, nextDepth, extendedMatch,
              extendedContainerMatch, coveredByWildCard, stream, crowd);

      if (extendedMatch.matched()) {
        ComposedRuleElementMatch nextContainerMatch = getContainerMatchOfNextElement(
                extendedContainerMatch, nextDepth);
        if (anchor == null) {
          anchor = stream.getVeryFirstBeforeWindow(after);
        }
        // TODO match and containermatch should be on the correct level!
        result = nextElement.continueMatch(after, anchor, extendedMatch, ruleApply,
                nextContainerMatch, sideStepOrigin, nextElement, stream, crowd);
//        List<RuleElementMatch> nextList = nextContainerMatch.getInnerMatches().get(nextElement);

        // cannot use container match since there could be new alternatives in the depth search
        boolean nextElementDidMatch = nextElementDidMatch(result, nextElement);

        if (!nextElementDidMatch) {
          moveOn(after, iterator, stream);
        } else {
          doneHere = true;
        }
      } else {
        // conditions of wildcard element did not match, try the next possible anchor for the
        // next rule element
        moveOn(after, iterator, stream);
      }
    }
    return result;
  }

  private void doMatchPotentialParentElements(boolean after, AnnotationFS annotation, int nextDepth,
          RuleMatch extendedMatch, ComposedRuleElementMatch extendedContainerMatch,
          AnnotationFS coveredByWildCard, RutaStream stream, InferenceCrowd crowd) {
    RuleElement element = this;
    ComposedRuleElementMatch containerMatch = extendedContainerMatch.getContainerMatch();
    for (int i = nextDepth; i > 0; i--) {
      // UIMA-6041: also doMatch for container conditions like (A #){XYZ} B;
      RuleElementContainer c = element.getContainer();
      if (c instanceof ComposedRuleElement) {
        ComposedRuleElement cre = (ComposedRuleElement) c;
        cre.doMatch(after, coveredByWildCard, extendedMatch,
                extendedContainerMatch.getContainerMatch(), annotation == null, stream, crowd);
        element = cre;
        containerMatch = containerMatch.getContainerMatch();
      }
    }
  }

  private AnnotationFS getNextAnchor(boolean after, AnnotationFS annotation,
          RuleElement nextElement, RuleMatch ruleMatch, ComposedRuleElementMatch containerMatch,
          RuleElement sideStepOrigin, RutaStream stream, InferenceCrowd crowd) {
    AnnotationFS nextAnchor = null;
    Pair<RuleElement, Integer> nextNext = getNextRuleElement(after, nextElement);
    if (nextNext != null && nextNext.getLeft() != null) {
      List<RuleMatch> tryWithNextNextRuleElement = tryWithNextRuleElement(nextNext.getLeft(), after,
              annotation, ruleMatch, null, containerMatch, nextNext.getRight().intValue(),
              sideStepOrigin, nextNext.getLeft(), stream, crowd);
      for (RuleMatch eachNextRuleMatch : tryWithNextNextRuleElement) {
        if (eachNextRuleMatch.matched()) {
          List<AnnotationFS> matchedAnnotationsOfElement = eachNextRuleMatch
                  .getMatchedAnnotationsOfElement(nextNext.getLeft());
          if (matchedAnnotationsOfElement != null && !matchedAnnotationsOfElement.isEmpty()) {
            nextAnchor = after ? matchedAnnotationsOfElement.get(0)
                    : matchedAnnotationsOfElement.get(matchedAnnotationsOfElement.size() - 1);
            break;
          }
        }
      }
    }
    return nextAnchor;
  }

  private boolean nextElementDidMatch(List<RuleMatch> result, RuleElement nextElement) {
    if (result == null || result.isEmpty()) {
      return false;
    }

    for (RuleMatch ruleMatch : result) {
      if (ruleMatch.matched()) {
        return true;
      }
    }
    for (RuleMatch ruleMatch : result) {
      List<List<RuleElementMatch>> matchInfo = ruleMatch.getMatchInfo(nextElement);
      List<RuleElementMatch> matches = matchInfo.get(matchInfo.size() - 1);
      if (matches != null) {
        for (RuleElementMatch ruleElementMatch : matches) {
          if (ruleElementMatch != null && ruleElementMatch.matched()) {
            return true;
          }
        }
      }

    }

    return false;
  }

  private ComposedRuleElementMatch getContainerMatchOfNextElement(
          ComposedRuleElementMatch extendedContainerMatch, int nextDepth) {
    ComposedRuleElementMatch result = extendedContainerMatch;
    for (int i = 0; i < nextDepth; i++) {
      result = result.getContainerMatch();
    }
    return result;
  }

  private FSIterator<AnnotationFS> getIterator(boolean after, AnnotationFS annotation,
          RuleElement nextElement, Type defaultType, RutaStream stream) {
    FSIterator<AnnotationFS> iterator = null;
    if (defaultType == null) {
      MatchContext context = new MatchContext(nextElement.getParent());
      RutaRuleElement re = (RutaRuleElement) nextElement;
      RutaMatcher matcher = re.getMatcher();
      if (matcher instanceof RutaAnnotationTypeMatcher) {
        RutaAnnotationTypeMatcher atm = (RutaAnnotationTypeMatcher) matcher;
        AnnotationTypeExpression expression = (AnnotationTypeExpression) atm.getExpression();
        if (expression.getAnnotationExpression() != null
                || expression.getAnnotationListExpression() != null) {
          iterator = new AnnotationListFSIterator(expression.getAnnotationList(context, stream));
          iterator.moveTo(annotation);
        } else {
          Type type = matcher.getType(parent, stream);
          iterator = getIteratorOfType(after, type, annotation, stream);
        }
      } else if (matcher != null) {
        // fallback
        Type type = matcher.getType(parent, stream);
        iterator = getIteratorOfType(after, type, annotation, stream);
      }
    } else {
      iterator = getIteratorOfType(after, defaultType, annotation, stream);
    }
    if (annotation != null && iterator != null && iterator.isValid()) {
      AnnotationFS pointer = iterator.get();
      if ((after && pointer.getEnd() == annotation.getEnd())
              || (!after && pointer.getBegin() == annotation.getBegin())) {
        moveOn(after, iterator, stream);
      }
    }
    return iterator;
  }

  private FSIterator<AnnotationFS> getIteratorOfType(boolean after, Type type,
          AnnotationFS annotation, RutaStream stream) {
    // TODO reimplement with cas select logic

    CAS cas = stream.getCas();
    // TODO adapt logic to changes in UIMA iterator behavior!
    FSIterator<AnnotationFS> result = null;
    if (stream.getDocumentAnnotation().equals(cas.getDocumentAnnotation())) {
      // no windowing needed
      if (annotation == null) {
        result = cas.getAnnotationIndex(type).withSnapshotIterators().iterator();
      } else {
        AnnotationFS pointer = stream.getAnchor(after, annotation);
        result = cas.getAnnotationIndex(type).withSnapshotIterators().iterator(pointer);
        if (!result.isValid()) {
          if (after) {
            // result.moveToFirst();
          } else {
            // HOTFIX caused by type priorities
            result.moveToLast();
            if (result.isValid()) {
              // HOTFIX avoid pointer to current annotation
              AnnotationFS current = result.get();
              if (current.getEnd() >= annotation.getBegin()) {
                result.moveToPrevious();
              }
            }
          }
        } else {
          if (!after) {
            result.moveToPrevious();
          }
        }
        if (annotation != null && result.isValid()) {
          // hotfix for index overflow...
          AnnotationFS a = result.get();
          // not greater equal because caller method will fix it for same positions, should be fixed
          // right here
          if (after) {
            if (a.getBegin() < annotation.getBegin()) {
              return null;
            }
          } else {
            if (a.getEnd() > annotation.getEnd()) {
              return null;
            }
          }
        }
      }
    } else {

      result = cas.getAnnotationIndex(type).select().coveredBy(stream.getDocumentAnnotation())
              .fsIterator();
      if (annotation == null) {
      } else {
        AnnotationFS pointer = stream.getAnchor(after, annotation);
        result.moveTo(pointer);

        if (!result.isValid()) {
          if (after) {
//            result.moveToFirst();
          } else {
            // TODO due to type priorities: RutaBasic is last -> moveTo will not work
            result.moveToLast();
            if (result.isValid()) {
              // HOTFIX avoid pointer to current annotation
              AnnotationFS current = result.get();
              if (current.getEnd() >= annotation.getBegin()) {
                result.moveToPrevious();
              }
            }
          }
        } else {
          if (!after) {
            result.moveToPrevious();
          }
        }
      }
    }

    return result;
  }

  private List<RuleMatch> tryWithNextLiteral(boolean after, AnnotationFS annotation,
          RutaRuleElement nextElement, RuleMatch ruleMatch, RuleApply ruleApply,
          ComposedRuleElementMatch containerMatch, int nextDepth, RuleElement sideStepOrigin,
          RutaStream stream, InferenceCrowd crowd) {
    List<RuleMatch> result = new ArrayList<>();
    RutaLiteralMatcher matcher = (RutaLiteralMatcher) nextElement.getMatcher();
    if (matcher == null) {
      return result;
    }
    IStringExpression expression = matcher.getExpression();
    MatchContext context = new MatchContext(this, ruleMatch, true);
    String stringValue = expression.getStringValue(context, stream);
    AnnotationFS documentAnnotation = stream.getDocumentAnnotation();
    int delta = documentAnnotation.getBegin();
    String document = documentAnnotation.getCoveredText();
    int pointer = 0;
    if (annotation != null) {
      pointer = annotation.getEnd() - delta;
    }
    int indexOf = 0;
    boolean doneHere = false;
    // TODO matching direction not included in document.indexOf(). Need another method here
    while (!doneHere && (indexOf = document.indexOf(stringValue, pointer)) < document.length()) {
      if (indexOf < 0) {
        // can't match, the next next element will see it.
        ComposedRuleElementMatch nextContainerMatch = getContainerMatchOfNextElement(containerMatch,
                nextDepth);
        nextElement.continueMatch(after, annotation, ruleMatch, ruleApply, nextContainerMatch,
                sideStepOrigin, null, stream, crowd);
        doneHere = true;
        break;
      }
      RutaBasic anchor = stream.getAnchor(after, indexOf + delta);
      RutaBasic endAnchor = stream.getAnchor(!after, indexOf + delta);
      ComposedRuleElementMatch extendedContainerMatch = containerMatch.copy();
      RuleMatch extendedMatch = ruleMatch.copy(extendedContainerMatch, after);
      AnnotationFS coveredByWildCard = getCoveredByWildCard(after, annotation, anchor, stream);
      doMatch(after, coveredByWildCard, extendedMatch, extendedContainerMatch, annotation == null,
              stream, crowd);
      doMatchPotentialParentElements(after, annotation, nextDepth, extendedMatch,
              extendedContainerMatch, coveredByWildCard, stream, crowd);
      if (extendedMatch.matched()) {
        ComposedRuleElementMatch nextContainerMatch = getContainerMatchOfNextElement(
                extendedContainerMatch, nextDepth);
        if (endAnchor == null) {
          result = nextElement.startMatch(extendedMatch, ruleApply, nextContainerMatch, nextElement,
                  stream, crowd);
        } else {
          result = nextElement.continueMatch(after, endAnchor, extendedMatch, ruleApply,
                  nextContainerMatch, sideStepOrigin, nextElement, stream, crowd);
        }
        List<RuleElementMatch> nextList = nextContainerMatch.getInnerMatches().get(nextElement);
        if (nextList == null || nextList.isEmpty()) {
          pointer = getNextPointer(after, anchor);
        } else {
          doneHere = true;
        }
      } else {
        pointer = getNextPointer(after, anchor);
      }
    }
    return result;
  }

  private int getNextPointer(boolean after, AnnotationFS anchor) {
    if (after) {
      return anchor.getEnd();
    } else {
      return anchor.getBegin();
    }
  }

  private void moveOn(boolean after, FSIterator<AnnotationFS> iterator, RutaStream stream) {
    if (after) {
      iterator.moveToNext();
    } else {
      iterator.moveToPrevious();
    }
    while (iterator.isValid() && !stream.isVisible(iterator.get())) {
      if (after) {
        iterator.moveToNext();
      } else {
        iterator.moveToPrevious();
      }
    }
  }

  private AnnotationFS getCoveredByWildCard(boolean after, AnnotationFS last, AnnotationFS next,
          RutaStream stream) {
    CAS cas = stream.getCas();
    Type type = cas.getAnnotationType();
    AnnotationFS documentAnnotation = stream.getDocumentAnnotation();

    // order like in the index
    AnnotationFS before = last;
    AnnotationFS later = next;
    if (!after) {
      before = next;
      later = last;
    }

    // without any information, match on everything
    int begin = documentAnnotation.getBegin();
    int end = documentAnnotation.getEnd();

    // limit offsets
    if (before != null) {
      begin = before.getEnd();
    }
    if (later != null) {
      end = later.getBegin();
    }

    int filteredBegin = begin;
    int filteredEnd = end;
    RutaBasic beginAnchor = stream.getBeginAnchor(begin);
    RutaBasic endAnchor = stream.getEndAnchor(end);
    if (beginAnchor != null && !stream.isVisible(beginAnchor)) {
      beginAnchor = stream.getBasicNextTo(false, beginAnchor);
      if (beginAnchor != null) {
        filteredBegin = beginAnchor.getBegin();
      }
    }
    if (endAnchor != null && !stream.isVisible(endAnchor)) {
      endAnchor = stream.getBasicNextTo(true, endAnchor);
      if (endAnchor != null) {
        filteredEnd = endAnchor.getEnd();
      }
    }

    if (filteredBegin < filteredEnd) {
      begin = filteredBegin;
      end = filteredEnd;
    } else {
      type = cas.getTypeSystem().getType(RutaEngine.OPTIONAL_TYPE);
    }
    AnnotationFS afs = cas.createAnnotation(type, begin, end);
    return afs;
  }

  @Override
  public void doMatch(boolean after, AnnotationFS annotation, RuleMatch ruleMatch,
          ComposedRuleElementMatch containerMatch, boolean ruleAnchor, RutaStream stream,
          InferenceCrowd crowd) {

    RuleElementMatch result = new RuleElementMatch(this, containerMatch);
    result.setRuleAnchor(ruleAnchor);
    List<EvaluatedCondition> evaluatedConditions = new ArrayList<>(
            conditions.size());
    boolean base = true;

    MatchContext context = new MatchContext(annotation, this, ruleMatch, true);

    List<AnnotationFS> textsMatched = annotation != null ? asList(annotation) : emptyList();

    result.setMatchInfo(base, textsMatched, stream);
    RutaEnvironment environment = context.getParent().getEnvironment();
    environment.addMatchToVariable(ruleMatch, this, context, stream);
    if (base) {
      for (AbstractRutaCondition condition : conditions) {
        crowd.beginVisit(condition, null);
        EvaluatedCondition eval = condition.eval(context, stream, crowd);
        crowd.endVisit(condition, null);
        evaluatedConditions.add(eval);
        if (!eval.isValue()) {
          break;
        }
      }
    }
    result.setConditionInfo(base, evaluatedConditions);
    if (result.matched()) {
      boolean inlinedRulesMatched = matchInlinedRules(ruleMatch, result, stream, crowd);
      result.setInlinedRulesMatched(inlinedRulesMatched);
    } else {
      // update label for failed match after evaluating conditions
      environment.removeVariableValue(getLabel(), context);
    }
    ruleMatch.setMatched(ruleMatch.matched() && result.matched());
  }

  @Override
  public List<RuleMatch> continueOwnMatch(boolean after, AnnotationFS annotation,
          RuleMatch ruleMatch, RuleApply ruleApply, ComposedRuleElementMatch containerMatch,
          RuleElement sideStepOrigin, RuleElement entryPoint, RutaStream stream,
          InferenceCrowd crowd) {
    // won't happen
    return Collections.emptyList();
  }

  @Override
  public Collection<AnnotationFS> getAnchors(RutaStream symbolStream) {
    // shouldn't happen
    // really? what about anchoring at start?
    return Collections.emptyList();
  }

  @Override
  public long estimateAnchors(RutaStream stream) {
    return Integer.MAX_VALUE;
  }

  @Override
  public String toString() {
    return "#" + (conditions.isEmpty() ? "" : "(" + conditions.toString() + ")" + "\\n")
            + (actions.isEmpty() ? "" : "{" + actions.toString() + "}");
  }

}
