/*
 * 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.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.rule.quantifier.RuleElementQuantifier;
import org.apache.uima.ruta.visitor.InferenceCrowd;

public class RutaRuleElement extends AbstractRuleElement {

  private RutaMatcher matcher;

  @SuppressWarnings("unchecked")
  protected final InferenceCrowd emptyCrowd = new InferenceCrowd(Collections.EMPTY_LIST);

  public RutaRuleElement(RutaMatcher matcher, RuleElementQuantifier quantifier,
          List<AbstractRutaCondition> conditions, List<AbstractRutaAction> actions,
          RuleElementContainer container, RutaBlock parent) {
    super(quantifier, conditions, actions, container, parent);
    this.matcher = matcher;
  }

  @Override
  public Collection<? extends AnnotationFS> getAnchors(RutaStream stream) {
    return matcher.getMatchingAnnotations(getParent(), stream);
  }

  @Override
  public List<RuleMatch> startMatch(RuleMatch ruleMatch, RuleApply ruleApply,
          ComposedRuleElementMatch containerMatch, RuleElement entryPoint, RutaStream stream,
          InferenceCrowd crowd) {
    List<RuleMatch> result = new ArrayList<>();
    Collection<? extends AnnotationFS> anchors = getAnchors(stream);
    boolean useAlternatives = anchors.size() != 1;
    for (AnnotationFS eachAnchor : anchors) {

      // clean up temp variables since we start a new matching iteration
      ruleMatch.getRule().clearOwnLabels();

      if (earlyExit(eachAnchor, ruleApply, stream)) {
        // ... for different matching paradigms that avoid some matches
        continue;
      }

      ComposedRuleElementMatch extendedContainerMatch = containerMatch;
      RuleMatch extendedMatch = ruleMatch;
      if (useAlternatives) {
        extendedContainerMatch = containerMatch.copy();
        extendedMatch = ruleMatch.copy(extendedContainerMatch, true);
      }
      doMatch(true, eachAnchor, extendedMatch, extendedContainerMatch, true, stream, crowd);
      if (equals(entryPoint) && ruleApply == null) {
        result.add(extendedMatch);
      } else if (extendedMatch.matched()) {
        RuleElement after = getContainer().getNextElement(true, this);
        RuleElement before = getContainer().getNextElement(false, this);
        RutaRuleElement sideStepOrigin = hasAncestor(false) ? this : null;
        MatchContext context = new MatchContext(this, extendedMatch, true);
        if (quantifier.continueMatch(true, context, eachAnchor, extendedContainerMatch, stream,
                crowd)) {
          List<RuleMatch> continueOwnMatch = continueOwnMatch(true, eachAnchor, extendedMatch,
                  ruleApply, extendedContainerMatch, sideStepOrigin, entryPoint, stream, crowd);
          result.addAll(continueOwnMatch);
        } else {
          if (after != null) {
            sideStepOrigin = hasAncestor(false) ? this : null;
            List<RuleMatch> continueMatch = after.continueMatch(true, eachAnchor, extendedMatch,
                    ruleApply, extendedContainerMatch, sideStepOrigin, entryPoint, stream, crowd);
            result.addAll(continueMatch);
          } else if ((stream.isDynamicAnchoring() || isStartAnchor()) && before != null) {
            sideStepOrigin = hasAncestor(true) ? this : null;
            List<RuleMatch> continueMatch = before.continueMatch(false, eachAnchor, extendedMatch,
                    ruleApply, extendedContainerMatch, sideStepOrigin, entryPoint, stream, crowd);
            result.addAll(continueMatch);
          }

          if (after == null && before == null) {
            if (getContainer() instanceof ComposedRuleElement) {
              sideStepOrigin = hasAncestor(false) ? this : null;
              ComposedRuleElement composed = (ComposedRuleElement) getContainer();
              List<RuleMatch> fallbackContinue = composed.fallbackContinue(true, false, eachAnchor,
                      extendedMatch, ruleApply, extendedContainerMatch, sideStepOrigin, entryPoint,
                      stream, crowd);
              result.addAll(fallbackContinue);
            } else if (getContainer() instanceof RuleElementIsolator) {
              // TODO move and refactor this:
              doneMatching(extendedMatch, ruleApply, stream, crowd);
            }
          }
        }
      } else {
        if (getContainer() instanceof ComposedRuleElement) {
          ComposedRuleElement composed = (ComposedRuleElement) getContainer();
          List<RuleMatch> fallbackContinue = composed.fallbackContinue(true, true, eachAnchor,
                  extendedMatch, ruleApply, extendedContainerMatch, null, entryPoint, stream,
                  crowd);
          result.addAll(fallbackContinue);
        }
      }
    }
    return result;
  }

  @Override
  public List<RuleMatch> continueOwnMatch(boolean after, AnnotationFS annotation,
          RuleMatch ruleMatch, RuleApply ruleApply, ComposedRuleElementMatch containerMatch,
          RuleElement sideStepOrigin, RuleElement entryPoint, RutaStream stream,
          InferenceCrowd crowd) {
    List<RuleMatch> result = new ArrayList<>();
    MatchContext context = new MatchContext(this, ruleMatch, after);
    if (quantifier.continueMatch(after, context, annotation, containerMatch, stream, crowd)) {
      boolean stopMatching = false;
      AnnotationFS eachAnchor = annotation;
      AnnotationFS lastAnchor = annotation;
      ComposedRuleElementMatch extendedContainerMatch = containerMatch;
      RuleMatch extendedMatch = ruleMatch;
      while (!stopMatching) {
        context = new MatchContext(this, extendedMatch, after);
        if (!quantifier.continueMatch(after, context, eachAnchor, extendedContainerMatch, stream,
                crowd)) {
          stopMatching = true;
          stepbackMatch(after, lastAnchor, extendedMatch, ruleApply, extendedContainerMatch,
                  sideStepOrigin, stream, crowd, entryPoint);
          break;
        }
        Collection<? extends AnnotationFS> nextAnnotations = getNextAnnotations(after, eachAnchor,
                stream);
        if (nextAnnotations.size() == 0) {
          stopMatching = true;
          result = stepbackMatch(after, eachAnchor, extendedMatch, ruleApply,
                  extendedContainerMatch, sideStepOrigin, stream, crowd, entryPoint);
        } else if (nextAnnotations.size() == 1) {
          lastAnchor = eachAnchor;
          eachAnchor = nextAnnotations.iterator().next();
          doMatch(after, eachAnchor, extendedMatch, extendedContainerMatch, false, stream, crowd);
          if (equals(entryPoint)) {
            result.add(extendedMatch);
          } else if (extendedMatch.matched()) {
            if (quantifier.continueMatch(after, context, eachAnchor, extendedContainerMatch, stream,
                    crowd)) {
              // continue in while loop
            } else {
              stopMatching = true;
              result = continueMatchSomewhereElse(after, false, eachAnchor, extendedMatch,
                      ruleApply, extendedContainerMatch, sideStepOrigin, entryPoint, stream, crowd);
            }
          } else {
            stopMatching = true;
            result = stepbackMatch(after, lastAnchor, extendedMatch, ruleApply,
                    extendedContainerMatch, sideStepOrigin, stream, crowd, entryPoint);
          }
        } else {
          stopMatching = true;
          result = continueMatch(after, lastAnchor, extendedMatch, ruleApply,
                  extendedContainerMatch, sideStepOrigin, entryPoint, stream, crowd);
        }
      }
    } else {
      result = stepbackMatch(after, annotation, ruleMatch, ruleApply, containerMatch,
              sideStepOrigin, stream, crowd, entryPoint);
    }
    return result;
  }

  protected List<RuleMatch> continueMatchSomewhereElse(boolean after, boolean failed,
          AnnotationFS eachAnchor, RuleMatch extendedMatch, RuleApply ruleApply,
          ComposedRuleElementMatch extendedContainerMatch, RuleElement sideStepOrigin,
          RuleElement entryPoint, RutaStream stream, InferenceCrowd crowd) {
    List<RuleMatch> result = new ArrayList<>();
    RuleElement nextRuleElement = getContainer().getNextElement(after, this);
    if (nextRuleElement != null) {
      result = nextRuleElement.continueMatch(after, eachAnchor, extendedMatch, ruleApply,
              extendedContainerMatch, sideStepOrigin, entryPoint, stream, crowd);
    } else if (sideStepOrigin != null && !failed) {
      result = sideStepOrigin.continueSideStep(after, extendedMatch, ruleApply,
              extendedContainerMatch, entryPoint, stream, crowd);
    } else if (getContainer() instanceof ComposedRuleElement) {
      ComposedRuleElement composed = (ComposedRuleElement) getContainer();
      result = composed.fallbackContinue(after, failed, eachAnchor, extendedMatch, ruleApply,
              extendedContainerMatch, sideStepOrigin, 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) {
    List<RuleMatch> result = new ArrayList<>();
    // if() for really lazy quantifiers
    MatchContext context = new MatchContext(this, ruleMatch, after);
    if (quantifier.continueMatch(after, context, annotation, containerMatch, stream, crowd)) {
      Collection<? extends AnnotationFS> nextAnnotations = getNextAnnotations(after, annotation,
              stream);
      if (isNotConsumable(nextAnnotations)) {
        result = stepbackMatch(after, annotation, ruleMatch, ruleApply, containerMatch,
                sideStepOrigin, stream, crowd, entryPoint);
      }
      boolean useAlternatives = nextAnnotations.size() > 1;
      for (AnnotationFS eachAnchor : nextAnnotations) {
        if (earlyExit(eachAnchor, ruleApply, stream)) {
          // ... for different matching paradigms that avoid some matches
          continue;
        }

        ComposedRuleElementMatch extendedContainerMatch = containerMatch;
        RuleMatch extendedMatch = ruleMatch;
        if (useAlternatives) {
          extendedContainerMatch = containerMatch.copy();
          extendedMatch = ruleMatch.copy(extendedContainerMatch, after);
        }
        doMatch(after, eachAnchor, extendedMatch, extendedContainerMatch, false, stream, crowd);

        if (equals(entryPoint) && ruleApply == null) {
          result.add(extendedMatch);
        } else if (extendedMatch.matched()) {
          context = new MatchContext(this, extendedMatch, after);
          if (quantifier.continueMatch(after, context, eachAnchor, extendedContainerMatch, stream,
                  crowd)) {
            List<RuleMatch> continueOwnMatch = continueOwnMatch(after, eachAnchor, extendedMatch,
                    ruleApply, extendedContainerMatch, sideStepOrigin, entryPoint, stream, crowd);
            result.addAll(continueOwnMatch);
          } else {
            List<RuleMatch> continueMatchSomewhereElse = continueMatchSomewhereElse(after, false,
                    eachAnchor, extendedMatch, ruleApply, extendedContainerMatch, sideStepOrigin,
                    entryPoint, stream, crowd);
            result.addAll(continueMatchSomewhereElse);
          }
        } else {
          if (equals(entryPoint)) {
            // hotfix for UIMA-3820
            result.add(extendedMatch);
          } else {
            List<RuleMatch> stepbackMatch = stepbackMatch(after, annotation, extendedMatch,
                    ruleApply, extendedContainerMatch, sideStepOrigin, stream, crowd, entryPoint);
            result.addAll(stepbackMatch);
          }
        }
      }
    } else {
      result = stepbackMatch(after, annotation, ruleMatch, ruleApply, containerMatch,
              sideStepOrigin, stream, crowd, entryPoint);
    }
    return result;
  }

  protected boolean isNotConsumable(Collection<? extends AnnotationFS> nextAnnotations) {
    return nextAnnotations.isEmpty();
  }

  protected List<RuleMatch> stepbackMatch(boolean after, AnnotationFS annotation,
          RuleMatch ruleMatch, RuleApply ruleApply, ComposedRuleElementMatch containerMatch,
          RuleElement sideStepOrigin, RutaStream stream, InferenceCrowd crowd,
          RuleElement entryPoint) {
    List<RuleMatch> result = new ArrayList<>();
    if (equals(entryPoint) && ruleApply == null) {
      result.add(ruleMatch);
      return result;
    }
    List<RuleElementMatch> matchInfo = getMatch(ruleMatch, containerMatch);
    MatchContext context = new MatchContext(this, ruleMatch, after);
    if (matchInfo == null) {
      context.getParent().getEnvironment().addMatchToVariable(ruleMatch, this, context, stream);
      if (quantifier.isOptional(context, stream)) {
        result = continueMatchSomewhereElse(after, false, annotation, ruleMatch, ruleApply,
                containerMatch, sideStepOrigin, entryPoint, stream, crowd);
      } else if (getContainer() instanceof ComposedRuleElement) {
        ComposedRuleElement cre = (ComposedRuleElement) getContainer();
        result = cre.fallbackContinue(after, true, annotation, ruleMatch, ruleApply, containerMatch,
                sideStepOrigin, entryPoint, stream, crowd);
        // was:
        // [Peter] why only check the parent? the grandparent could be optional!
        // should we add the second part again for the explanation component?
        // if (cre.getQuantifier().isOptional(parent, stream)) {
        // result = continueMatchSomewhereElse(after, true, annotation, ruleMatch, ruleApply,
        // containerMatch, sideStepOrigin, entryPoint, stream, crowd);
        // } else {
        // RuleElementMatch failedMatch = new RuleElementMatch(this, containerMatch);
        // failedMatch.setBaseConditionMatched(false);
        // containerMatch.addInnerMatch(this, failedMatch, stream);
        // ComposedRuleElement composed = (ComposedRuleElement) getContainer();
        // result = composed.fallbackContinue(after, true, annotation, ruleMatch, ruleApply,
        // containerMatch, sideStepOrigin, entryPoint, stream, crowd);
        // }
      }
    } else {
      List<RuleElementMatch> evaluateMatches = quantifier.evaluateMatches(matchInfo, context,
              stream, crowd);
      // TODO enforce match update?
      ruleMatch.setMatched(evaluateMatches != null);
      if (ruleMatch.matched()) {
        result = continueMatchSomewhereElse(after, false, annotation, ruleMatch, ruleApply,
                containerMatch, sideStepOrigin, entryPoint, stream, crowd);
      } else {
        if (getContainer() instanceof ComposedRuleElement) {
          ComposedRuleElement composed = (ComposedRuleElement) getContainer();
          List<RuleMatch> fallbackContinue = composed.fallbackContinue(after, true, annotation,
                  ruleMatch, ruleApply, containerMatch, sideStepOrigin, entryPoint, stream, crowd);
          result.addAll(fallbackContinue);
        } else {
          // should never happen!
          doneMatching(ruleMatch, ruleApply, stream, crowd);
        }
      }
    }
    return result;
  }

  @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 = matcher.match(annotation, stream, getParent());
    boolean base = true;
    MatchContext context = new MatchContext(annotation, this, ruleMatch, after);

    List<AnnotationFS> textsMatched = annotation != null ? asList(annotation) : emptyList();

    // already set the matched text and inform others
    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 String toString() {
    String simpleName = getQuantifier().getClass().getSimpleName();
    return matcher.toString() + " " + (simpleName.equals("NormalQuantifier") ? "" : simpleName)
    // + (conditions.isEmpty() ? "" : "(" + conditions.toString() + ")" + "\\n")
    // + (actions.isEmpty() ? "" : "{" + actions.toString() + "}")
    ;
  }

  public RutaMatcher getMatcher() {
    return matcher;
  }

  @Override
  public List<AbstractRutaCondition> getConditions() {
    return conditions;
  }

  @Override
  public List<AbstractRutaAction> getActions() {
    return actions;
  }

  @Override
  public RutaBlock getParent() {
    return parent;
  }

  @Override
  public long estimateAnchors(RutaStream stream) {
    // TODO what about the match context?
    if (quantifier.isOptional(null, stream)) {
      return matcher.estimateAnchors(parent, stream) + Integer.MAX_VALUE;
    }
    return matcher.estimateAnchors(parent, stream);
  }

  public Collection<? extends AnnotationFS> getNextAnnotations(boolean after,
          AnnotationFS annotation, RutaStream stream) {
    if (after) {
      return matcher.getAnnotationsAfter(this, annotation, getParent(), stream);
    } else {
      return matcher.getAnnotationsBefore(this, annotation, getParent(), stream);
    }
  }

}
