/*
 * Copyright 2016 The Depan Project Authors
 *
 * Licensed 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 com.google.devtools.depan.nodes.filters.sequence;

import com.google.devtools.depan.model.GraphNode;
import com.google.devtools.depan.nodes.filters.model.ContextKey;
import com.google.devtools.depan.nodes.filters.model.ContextualFilter;

import com.google.common.base.Strings;

import java.text.MessageFormat;
import java.util.Collection;

/**
 * @author <a href="leeca@pnambic.com">Lee Carver</a>
 */
public class ClosureFilter extends BasicFilter {

  private static final String FILTER_NAME_DEFAULT = "Closure filter";

  private ContextualFilter filter;

  private ContextKey context;

  public ClosureFilter() {
    super(FILTER_NAME_DEFAULT);
  }

  public ContextualFilter getFilter() {
    return filter;
  }

  public void setFilter(ContextualFilter filter) {
    this.filter = filter;
  }

  public ContextKey getContext() {
    return context;
  }

  public void setContext(ContextKey context) {
    this.context = context;
  }

  @Override
  public String buildSummary() {
    String filterName = getFilterName();
    if (null == filterName) {
      return "Closure filter";
    }
    return MessageFormat.format("Closure on {0}", filterName);
  }

  private String getFilterName() {
    if (null == filter) {
      return null;
    }
    String result = filter.getName();
    if (Strings.isNullOrEmpty(result)) {
      return null;
    }
    return result;
  }

  @Override
  public Collection<GraphNode> computeNodes(Collection<GraphNode> nodes) {
    return null;
  }
}

@@ -887,16 +887,55 @@
 Strings;
+%0Aimport com.google.common.collect.Sets;
 %0A%0Aimport
@@ -1213,39 +1213,8 @@
 r;%0A%0A
-  private ContextKey context;%0A%0A
   pu
@@ -1269,24 +1269,138 @@
 AULT);%0A  %7D%0A%0A
+  @Override%0A  public Collection%3C? extends ContextKey%3E getContextKeys() %7B%0A    return filter.getContextKeys();%0A  %7D%0A%0A
   public Con
@@ -1537,148 +1537,8 @@
  %7D%0A%0A
-  public ContextKey getContext() %7B%0A    return context;%0A  %7D%0A%0A  public void setContext(ContextKey context) %7B%0A    this.context = context;%0A  %7D%0A%0A
   @O
@@ -2055,31 +2055,344 @@
 odes) %7B%0A    
-return null
+filter.receiveContext(getFilterContext());%0A%0A    Collection%3CGraphNode%3E result = Sets.newHashSet(nodes);%0A    Collection%3CGraphNode%3E update = Sets.newHashSet(result);%0A%0A    while (!update.isEmpty()) %7B%0A      update = filter.computeNodes(update);%0A      update.removeAll(result);%0A      result.addAll(update);%0A    %7D%0A    return result
 ;%0A  %7D%0A%7D%0A

Implement closure filter.