/*
 * 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.expression.feature;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.uima.cas.Feature;
import org.apache.uima.cas.FeatureStructure;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.jcas.cas.FSArray;
import org.apache.uima.ruta.RutaStream;
import org.apache.uima.ruta.UIMAConstants;
import org.apache.uima.ruta.expression.MatchReference;
import org.apache.uima.ruta.expression.annotation.IAnnotationExpression;
import org.apache.uima.ruta.expression.type.ITypeExpression;
import org.apache.uima.ruta.rule.MatchContext;
import org.apache.uima.ruta.utils.IndexedReference;
import org.apache.uima.ruta.utils.ParsingUtils;

public class SimpleFeatureExpression extends FeatureExpression {

  private MatchReference mr;

  public SimpleFeatureExpression(MatchReference mr) {

    super();
    this.mr = mr;
  }

  @Override
  public Feature getFeature(MatchContext context, RutaStream stream) {

    List<Feature> features = this.getFeatures(context, stream);
    if (features != null && !features.isEmpty()) {
      Feature feature = features.get(features.size() - 1);
      if (feature instanceof LazyFeature) {
        LazyFeature lazyFeature = (LazyFeature) feature;
        AnnotationFS annotation = context.getAnnotation();
        List<AnnotationFS> targetAnnotation = this.getTargetAnnotation(annotation, this, context,
                stream);
        if (targetAnnotation != null && !targetAnnotation.isEmpty()) {
          annotation = targetAnnotation.get(0);
        }
        if (features.size() == 1) {
          feature = lazyFeature.initialize(annotation);
        }
      }
      return feature;
    } else {
      return null;
    }
  }

  @Override
  public List<Feature> getFeatures(MatchContext context, RutaStream stream) {

    List<Feature> result = new ArrayList<Feature>();
    Type type = this.getInitialType(context, stream);
    Feature feature = null;
    for (String each : this.getFeatureStringList(context, stream)) {
      IndexedReference indexedReference = ParsingUtils.parseIndexedReference(each);
      if (indexedReference.index != -1) {
        Feature delegate = type.getFeatureByBaseName(indexedReference.reference);
        if (delegate != null) {
          feature = new IndexedFeature(delegate, indexedReference.index);
        } else {
          throw new IllegalArgumentException("Not able to access feature " + each + " of type "
                  + type.getName() + "in script " + context.getParent().getName());
        }
      } else if (StringUtils.equals(each, UIMAConstants.FEATURE_COVERED_TEXT)
              || StringUtils.equals(each, UIMAConstants.FEATURE_COVERED_TEXT_SHORT)) {
        if (type != null) {
          feature = type.getFeatureByBaseName(each);
          if (feature == null) {
            // there is no explicit feature for coveredText
            feature = new CoveredTextFeature();
          }
        } else {
          // also allow for unknown types
          feature = new CoveredTextFeature();
        }
      } else if (StringUtils.equals(each, UIMAConstants.FEATURE_TYPE)) {
        feature = new TypeFeature();
      } else if (type == null || type.isArray()) {
        // lazy check of range
        feature = new LazyFeature(each, context.getParent());
      } else {
        feature = type.getFeatureByBaseName(each);
        if (feature == null) {
          // type maybe not specific enough
          feature = new LazyFeature(each, context.getParent());
        }
      }
      result.add(feature);
      if (feature instanceof LazyFeature) {
        type = null;
      } else if (feature != null) {
        type = feature.getRange();
      }
    }
    return result;
  }

  @Override
  public Type getInitialType(MatchContext context, RutaStream stream) {

    ITypeExpression typeExpression = this.mr.getTypeExpression(context, stream);
    IAnnotationExpression annotationExpression = this.mr.getAnnotationExpression(context, stream);
    IAnnotationExpression annotationListExpression = this.mr.getAnnotationExpression(context,
            stream);
    if (typeExpression != null) {
      return typeExpression.getType(context, stream);
    } else if (annotationExpression != null) {
      AnnotationFS annotation = annotationExpression.getAnnotation(context, stream);
      if (annotation != null) {
        return annotation.getType();
      }
    } else if (annotationListExpression != null) {
      AnnotationFS annotation = annotationListExpression.getAnnotation(context, stream);
      if (annotation != null) {
        return annotation.getType();
      }
    }
    return null;
  }

  @Override
  public List<String> getFeatureStringList(MatchContext context, RutaStream stream) {

    return this.mr.getFeatureList();
  }

  @Override
  public Collection<? extends AnnotationFS> getAnnotations(
          Collection<? extends FeatureStructure> featureStructures, boolean checkOnFeatureValue,
          MatchContext context, RutaStream stream) {

    Collection<AnnotationFS> result = new ArrayList<>();
    List<Feature> features = this.getFeatures(context, stream);
    if (features != null && !features.isEmpty()) {
      this.collectFeatureStructures(featureStructures, features, checkOnFeatureValue, true, result,
              stream, context);
      return result;
    } else {
      return this.filterAnnotations(featureStructures);
    }
  }

  @Override
  public Collection<? extends FeatureStructure> getFeatureStructures(
          Collection<? extends FeatureStructure> featureStructures, boolean checkOnFeatureValue,
          MatchContext context, RutaStream stream) {

    Collection<FeatureStructure> result = new ArrayList<>();
    List<Feature> features = this.getFeatures(context, stream);
    if (features != null && !features.isEmpty()) {
      this.collectFeatureStructures(featureStructures, features, checkOnFeatureValue, false, result,
              stream, context);
      return result;
    } else {
      return featureStructures;
    }
  }

  private <T> void collectFeatureStructures(
          Collection<? extends FeatureStructure> featureStructures, List<Feature> features,
          boolean checkOnFeatureValue, boolean onlyAnnotations, Collection<T> result,
          RutaStream stream, MatchContext context) {

    for (FeatureStructure each : featureStructures) {
      this.collectFeatureStructures(each, features, checkOnFeatureValue, onlyAnnotations, null,
              result, stream, context);
    }
  }

  @SuppressWarnings("unchecked")
  private <T> void collectFeatureStructures(FeatureStructure featureStructure,
          List<Feature> features, boolean checkOnFeatureValue, boolean collectOnlyAnnotations,
          T lastValidFeatureStructure, Collection<T> result, RutaStream stream,
          MatchContext context) {

    if (featureStructure == null) {
      return;
    }
    if (!collectOnlyAnnotations) {
      if (!featureStructure.getType().isArray()) {
        lastValidFeatureStructure = (T) featureStructure;
      }
    } else if (featureStructure instanceof AnnotationFS) {
      lastValidFeatureStructure = (T) featureStructure;
    }

    Feature currentFeature = null;
    List<Feature> tail = null;

    if (features != null && !features.isEmpty()) {
      currentFeature = features.get(0);
      if (currentFeature instanceof LazyFeature) {
        LazyFeature lazyFeature = (LazyFeature) currentFeature;
        Feature delegate = lazyFeature.initialize(featureStructure);
        if (delegate == null) {
          throw new RuntimeException("Invalid feature! Feature '" + lazyFeature.getFeatureName()
                  + "' is not defined for type '" + featureStructure.getType() + "' in script "
                  + context.getParent().getName() + ".");
        } else {
          currentFeature = delegate;
        }
      }
      tail = features.subList(1, features.size());
    }

    if (currentFeature == null || currentFeature instanceof CoveredTextFeature
            || currentFeature instanceof TypeFeature || currentFeature.getRange().isPrimitive()) {
      // feature == null -> this is not a real feature
      if (this instanceof FeatureMatchExpression) {
        FeatureMatchExpression fme = (FeatureMatchExpression) this;
        if (checkOnFeatureValue) {
          if (fme.checkFeatureValue(featureStructure, currentFeature, context, stream)) {
            result.add(lastValidFeatureStructure);
          }
        } else {
          result.add(lastValidFeatureStructure);
        }
      } else {
        result.add(lastValidFeatureStructure);
      }
    } else {
      this.collectFeatureStructures(featureStructure, currentFeature, tail, checkOnFeatureValue,
              collectOnlyAnnotations, lastValidFeatureStructure, result, stream, context);
    }
  }

  private <T> void collectFeatureStructures(FeatureStructure featureStructure,
          Feature currentFeature, List<Feature> tail, boolean checkOnFeatureValue,
          boolean collectOnlyAnnotations, T lastValidFeatureStructure, Collection<T> result,
          RutaStream stream, MatchContext context) {

    // stop early for match expressions
    if (this instanceof FeatureMatchExpression && (tail == null || tail.isEmpty())) {
      FeatureMatchExpression fme = (FeatureMatchExpression) this;
      if (checkOnFeatureValue) {
        if (fme.checkFeatureValue(featureStructure, currentFeature, context, stream)) {
          result.add(lastValidFeatureStructure);
        }
      } else {
        result.add(lastValidFeatureStructure);
      }
      return;
    }

    int index = -1;
    if (currentFeature instanceof IndexedFeature) {
      IndexedFeature indexedFeature = (IndexedFeature) currentFeature;
      currentFeature = indexedFeature.getDelegate();
      index = indexedFeature.getIndex();
    }

    FeatureStructure value = featureStructure.getFeatureValue(currentFeature);
    if (value instanceof AnnotationFS) {
      AnnotationFS next = (AnnotationFS) value;
      this.collectFeatureStructures(next, tail, checkOnFeatureValue, collectOnlyAnnotations,
              lastValidFeatureStructure, result, stream, context);
    } else if (value instanceof FSArray && index >= 0) {
      FSArray array = (FSArray) value;
      if (index < array.size()) {
        FeatureStructure fs = array.get(index);
        if (fs instanceof AnnotationFS) {
          AnnotationFS next = (AnnotationFS) fs;
          this.collectFeatureStructures(next, tail, checkOnFeatureValue, collectOnlyAnnotations,
                  lastValidFeatureStructure, result, stream, context);
        }
      }
    } else if (value instanceof FSArray) {
      FSArray array = (FSArray) value;
      for (int i = 0; i < array.size(); i++) {
        FeatureStructure fs = array.get(i);
        this.collectFeatureStructures(fs, tail, checkOnFeatureValue, collectOnlyAnnotations,
                lastValidFeatureStructure, result, stream, context);
      }
    } else if (value != null && !value.getType().isPrimitive()) {
      // feature structure feature values
      this.collectFeatureStructures(value, tail, checkOnFeatureValue, collectOnlyAnnotations,
              lastValidFeatureStructure, result, stream, context);
    } else if (value != null) {
      // primitive? -> return last annotation for further processing
      result.add(lastValidFeatureStructure);
      // throw new IllegalArgumentException(value.getType()
      // + " is not supported in a feature match expression (" + mr.getMatch() + ").");
    }
  }

  public MatchReference getMatchReference() {

    return this.mr;
  }

  @Override
  public String toString() {

    return this.mr.getMatch();
  }

  private Collection<AnnotationFS> filterAnnotations(
          Collection<? extends FeatureStructure> featureStructures) {

    Collection<AnnotationFS> result = new ArrayList<>(featureStructures.size());

    for (FeatureStructure featureStructure : featureStructures) {
      if (featureStructure instanceof AnnotationFS) {
        result.add((AnnotationFS) featureStructure);
      }
    }
    return result;
  }

}
