/*
 * 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 java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.uima.cas.CAS;
import org.apache.uima.cas.ConstraintFactory;
import org.apache.uima.cas.FSIntConstraint;
import org.apache.uima.cas.FSIterator;
import org.apache.uima.cas.FSMatchConstraint;
import org.apache.uima.cas.FeaturePath;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.ruta.constraint.BasicTypeConstraint;
import org.apache.uima.ruta.constraint.NotConstraint;

public class FilterManager {

  private final Collection<Type> defaultFilterTypes;

  private final FSMatchConstraint additionalWindow;

  private final AnnotationFS windowAnnotation;

  private final Type windowType;

  private Collection<Type> currentFilterTypes;

  private Collection<Type> currentRetainTypes;

  private ConstraintFactory cf;

  private final CAS cas;

  private Set<Type> currentHiddenTypes;

  private boolean emptyIsInvisible;

  public FilterManager(Collection<Type> defaultFilterTypes, boolean emptyIsInvisible, CAS cas) {
    super();
    this.defaultFilterTypes = defaultFilterTypes;

    currentFilterTypes = new ArrayList<Type>();
    currentRetainTypes = new ArrayList<Type>();

    cf = cas.getConstraintFactory();

    this.windowAnnotation = null;
    this.windowType = null;
    this.additionalWindow = null;
    this.emptyIsInvisible = emptyIsInvisible;

    this.cas = cas;
  }

  public FilterManager(Collection<Type> defaultFilterTypes, Collection<Type> filterTypes,
          Collection<Type> retainTypes, AnnotationFS windowAnnotation, Type windowType,
          boolean emptyIsInvisible, CAS cas) {
    super();
    this.defaultFilterTypes = defaultFilterTypes;

    currentFilterTypes = new ArrayList<Type>(filterTypes);
    currentRetainTypes = new ArrayList<Type>(retainTypes);

    cf = cas.getConstraintFactory();

    this.windowAnnotation = windowAnnotation;
    this.windowType = windowType;
    this.additionalWindow = createWindowConstraint(windowAnnotation, cas);
    this.emptyIsInvisible = emptyIsInvisible;

    this.cas = cas;
  }

  private FSMatchConstraint createWindowConstraint(AnnotationFS windowAnnotation, CAS cas) {
    if (windowAnnotation == null)
      return null;
    FeaturePath beginFP = cas.createFeaturePath();
    Type type = windowAnnotation.getType();
    beginFP.addFeature(type.getFeatureByBaseName("begin"));
    FSIntConstraint intConstraint = cf.createIntConstraint();
    intConstraint.geq(windowAnnotation.getBegin());
    FSMatchConstraint beginConstraint = cf.embedConstraint(beginFP, intConstraint);

    FeaturePath endFP = cas.createFeaturePath();
    endFP.addFeature(type.getFeatureByBaseName("end"));
    intConstraint = cf.createIntConstraint();
    intConstraint.leq(windowAnnotation.getEnd());
    FSMatchConstraint endConstraint = cf.embedConstraint(endFP, intConstraint);

    FSMatchConstraint windowConstraint = cf.and(beginConstraint, endConstraint);
    return windowConstraint;
  }

  public FSMatchConstraint getDefaultConstraint() {
    return createCurrentConstraint(true);
  }

  private FSMatchConstraint createCurrentConstraint(boolean windowConstraint) {
    Set<Type> filterTypes = new HashSet<Type>();
    filterTypes.addAll(defaultFilterTypes);
    filterTypes.addAll(currentFilterTypes);
    filterTypes.removeAll(currentRetainTypes);
    for (Type type : currentRetainTypes) {
      if (type != null) {
        List<Type> subsumedTypes = cas.getTypeSystem().getProperlySubsumedTypes(type);
        filterTypes.removeAll(subsumedTypes);
      }
    }
    currentHiddenTypes = filterTypes;
    FSMatchConstraint typeConstraint = createTypeConstraint(filterTypes);

    FSMatchConstraint constraint = new NotConstraint(typeConstraint);
    if (additionalWindow != null && windowConstraint) {
      constraint = cf.and(additionalWindow, constraint);
    }
    return constraint;
  }

  private FSMatchConstraint createTypeConstraint(Collection<Type> types) {
    BasicTypeConstraint result = new BasicTypeConstraint(types, emptyIsInvisible);
    return result;
  }

  public void retainTypes(List<Type> list) {
    currentRetainTypes = list;
  }

  public void filterTypes(List<Type> list) {
    currentFilterTypes = list;
  }

  public void addFilterTypes(List<Type> types) {
    currentFilterTypes.addAll(types);
  }

  public void addRetainTypes(List<Type> types) {
    currentRetainTypes.addAll(types);
  }

  public void removeFilterTypes(List<Type> types) {
    currentFilterTypes.removeAll(types);
  }

  public void removeRetainTypes(List<Type> types) {
    currentRetainTypes.removeAll(types);
  }

  public Collection<Type> getDefaultFilterTypes() {
    return defaultFilterTypes;
  }

  public FSMatchConstraint getAdditionalWindow() {
    return additionalWindow;
  }

  public Collection<Type> getCurrentFilterTypes() {
    return currentFilterTypes;
  }

  public Collection<Type> getCurrentRetainTypes() {
    return currentRetainTypes;
  }

  public AnnotationFS getWindowAnnotation() {
    return windowAnnotation;
  }

  public Type getWindowType() {
    return windowType;
  }

  public FSIterator<AnnotationFS> createFilteredIterator(CAS cas, Type basicType) {
    if (windowAnnotation != null) {
      FSIterator<AnnotationFS> windowIt = cas.getAnnotationIndex(basicType)
              .subiterator(windowAnnotation);
      FSIterator<AnnotationFS> iterator = cas.createFilteredIterator(windowIt,
              createCurrentConstraint(false));
      return iterator;
    } else {
      FSIterator<AnnotationFS> iterator = cas.createFilteredIterator(
              cas.getAnnotationIndex(basicType).iterator(), createCurrentConstraint(false));
      return iterator;
    }
  }

  public Set<Type> getCurrentHiddenTypes() {
    return currentHiddenTypes;
  }

}
