/*
 * Copyright 2010 Google Inc.
 * 
 * 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.gwt.validation.rebind;

import com.google.gwt.thirdparty.guava.common.base.Function;
import com.google.gwt.thirdparty.guava.common.base.Functions;
import com.google.gwt.thirdparty.guava.common.base.Predicate;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableList;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableSet;
import com.google.gwt.thirdparty.guava.common.collect.Iterables;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
import com.google.gwt.thirdparty.guava.common.collect.Sets;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * Static utilities for the validation rebind package.
 */
class Util {

  /**
   * Creates a Predicate that returns false if source contains an associated
   * class that is a super type of the class associated with the tested T.
   *
   * @param <T> the type to test
   * @param source the set of <T> to look for class matches.
   * @param toClass Function from T to Class
   * @return newly create predicate.
   */
  static <T> Predicate<T> createMostSpecificMatchPredicate(
      final Iterable<T> source, final Function<T, Class<?>> toClass) {
    return new Predicate<T>() {

      public boolean apply(T input) {
        Class<?> inputClass = toClass.apply(input);
        for (Class<?> match : Iterables.transform(source, toClass)) {
          if (!inputClass.equals(match) && inputClass.isAssignableFrom(match)) {
            return false;
          }
        }
        return true;
      }
    };
  }

  /**
   * Selects first only the classes that are assignable from the target, and
   * then returns the most specific matching classes.
   *
   * @param target the Class to match
   * @param availableClasses classes to search
   * @return Set of only the most specific classes that match the target.
   */
  static Set<Class<?>> findBestMatches(Class<?> target,
      Set<Class<?>> availableClasses) {
    Set<Class<?>> matches = new HashSet<Class<?>>();
    if (availableClasses.contains(target)) {
      return ImmutableSet.<Class<?>> of(target);
    } else {
      for (Class<?> clazz : availableClasses) {
        if (clazz.isAssignableFrom(target)) {
          matches.add(clazz);
        }
      }
    }
    Predicate<Class<?>> moreSpecificClassPredicate = createMostSpecificMatchPredicate(
        matches, Functions.<Class<?>> identity());
    return Sets.filter(matches, moreSpecificClassPredicate);
  }

  /**
   * Returns a Immutable List sorted with the most specific associated class
   * first. Each element is guaranteed to not be assignable to any element that
   * appears before it in the list.
   */
  static <T> ImmutableList<T> sortMostSpecificFirst(Iterable<T> classes,
      Function<T, Class<?>> toClass) {
    List<T> working = Lists.newArrayList();
    // strip duplicates
    for (T t : classes) {
      if (!working.contains(t)) {
        working.add(t);
      }
    }
    List<T> sorted = Lists.newArrayList();
    Predicate<T> mostSpecific = createMostSpecificMatchPredicate(working,
        toClass);
    boolean changed = false;
    do {
      changed = false;
      for (Iterator<T> iterator = working.iterator(); iterator.hasNext();) {
        T t = iterator.next();
        if (mostSpecific.apply(t)) {
          sorted.add(t);
          iterator.remove();
          changed = true;
        }
      }
    } while (changed);
    if (!working.isEmpty()) {
      throw new IllegalStateException(
          "Unable to find a element that does not have a more specific element in the set "
              + working);
    }
    return ImmutableList.copyOf(sorted);
  }

  private Util() {
  }
}
