/*
 * 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.dev.util.editdistance;

/**
 * A collection of instance generators for the GeneralEditDistance interface.
 */
public class GeneralEditDistances {
  /**
   * Chooses the best implementation of Levenshtein string edit distance
   * available at the current time.
   */
  /*
   * As of 2007-08-23, the best algorithm known (to the author=mwyoung) for
   * short strings is one due to Eugene Myers, except for the special case
   * where the distance limit is 0 or 1.  The Myers algorithm also has good
   * worst-case performance for long strings when the edit distance is not
   * reasonably bounded.
   *
   * When there is a good bound, a variant of the Ukkonen algorithm due to
   * Berghel and Roach (modified by Michael Young to use linear space)
   * is faster for long strings.
   *
   * Note that other algorithms that perform better in some cases for running
   * text searches do not outperform Myers for rigid distance computations.
   * Notably:
   *   Navarro/Baeza-Yates (Algorithmica 23,2) simulates an NFA with an
   *   epsilon-cycle on the initial state (appropriate for running texts)
   *   and reports success without computing exact distance.  When adjusted
   *   to a fixed starting point and computing distance, its state machine
   *   is larger and it underperforms.
   *
   *   BITAP (Baeza-Yates/Gonnet, Manber/Wu) also simulates an NFA, and
   *   Navarro claims that it wins for small patterns and small limits for
   *   running search.  Experiments with a Java implementation showed that
   *   it beat Myers on pure string edit distance only for limits where the
   *   special 0-1 limit applied, where special-case comparison beats all.
   *
   * A survey of algorithms for running text search by Navarro appeared
   * in ACM Computing Surveys 33#1: http://portal.acm.org/citation.cfm?id=375365
   * Another algorithm (Four Russians) that Navarro claims superior for very
   * long patterns and high limits was not evaluated for inclusion here.
   * Filtering algorithms also improve running search, but do not help
   * for pure edit distance.
   */
  private static class Levenshtein implements GeneralEditDistance {
    /**
     * Long+bounded implementation class: distance-only Berghel-Roach
     */
    private ModifiedBerghelRoachEditDistance berghel;

    /**
     * Short/unbounded implementation class: Myers bit-parallel
     */
    private MyersBitParallelEditDistance myers;

    /**
     * Saved pattern, for specialized comparisons
     */    
    private final CharSequence pattern;

    /**
     * Length of saved pattern
     */
    private final int patternLength;

    private Levenshtein(CharSequence pattern) {
      this.pattern = pattern;
      this.patternLength = pattern.length();
    }

    public GeneralEditDistance duplicate() {
      Levenshtein dup = new Levenshtein(pattern);

      /* Duplicate the Myers engine, as it is cheaper than rebuilding */
      if (this.myers != null) {
        dup.myers = (MyersBitParallelEditDistance) this.myers.duplicate();
      }
      
      /* Do not duplicate the Berghel engine; it provides no savings. */

      return dup;
    }

    public int getDistance(CharSequence target, int limit) {
      /* When the limit is 0 or 1, specialized comparisons are much faster. */
      if (limit <= 1) {
        return limit == 0 ?
                 (pattern.equals(target) ? 0 : 1) :
                 atMostOneError(pattern, target);
      }

      /*
       * The best algorithm for long strings depends on the resulting
       * edit distance (or the limit placed on it).  Without further
       * information on the likelihood of a low distance, we guess
       * based on the provided limit.  We currently lean toward using
       * the Myers algorithm unless we are pretty sure that the
       * Berghel-Roach algorithm will win (based on the limit).
       *
       * Note that when the string lengths are small (fewer characters
       * than bits in a long), Myers wins regardless of limit.
       */
      if ((patternLength > 64)
          && (limit < (target.length() / 10))) {
        if (berghel == null) {
          berghel = ModifiedBerghelRoachEditDistance.getInstance(pattern);
        }
        return berghel.getDistance(target, limit);
      }

      if (myers == null) {
        myers = MyersBitParallelEditDistance.getInstance(pattern);
      }

      return myers.getDistance(target, limit);
    }
  }

  /**
   * Compares two strings for at most one insert/delete/substitute difference.
   * Since operations cannot be composed, a simple case analysis is possible.
   *
   * @param s1 one string to be compared
   * @param s2 the other string to be compared
   * @return Levenshtein edit distance if no greater than 1;
   *         otherwise, more than 1
   */
  public static int atMostOneError(CharSequence s1, CharSequence s2) {
    int s1Length = s1.length();
    int s2Length = s2.length();
    int errors = 0;             /* running count of edits required */

    switch(s2Length - s1Length) {
      /*
       * Strings are the same length.  No single insert/delete is possible;
       * at most one substitution can be present.
       */
      case 0:
        for (int i = 0; i < s2Length; i++) {
          if ((s2.charAt(i) != s1.charAt(i)) && (errors++ != 0)) {
            break;
          }
        }
        return errors;

      /*
       * Strings differ in length by 1, so we have an insertion
       * (and therefore cannot have any other substitutions).
       */
      case 1: /* s2Length > s1Length */
        for (int i = 0; i < s1Length; i++) {
          if (s2.charAt(i) != s1.charAt(i)) {
            for (; i < s1Length; i++) {
              if (s2.charAt(i + 1) != s1.charAt(i)) {
                return 2;
              }
            }
            return 1;
          }
        }
        return 1;

      /* Same as above case, with strings reversed */
      case -1: /* s1Length > s2Length */
        for (int i = 0; i < s2Length; i++) {
          if (s2.charAt(i) != s1.charAt(i)) {
            for (; i < s2Length; i++) {
              if (s2.charAt(i) != s1.charAt(i + 1)) {
                return 2;
              }
            }
            return 1;
          }
        }
        return 1;

      /* Edit distance is at least difference in lengths; more than 1 here. */
      default:
        return 2;
    }
  }

  /**
   * Generates an GeneralEditDistance engine for a particular pattern string
   * based on Levenshtein distance.  Caller must ensure that the
   * pattern does not change (consider using pattern.toString() if
   * necessary) as long as the generated object is to be used.
   *
   * @param pattern a string from which distance computations are desired
   * @return an engine for computing Levenshtein distances from that pattern
   */
  public static GeneralEditDistance
      getLevenshteinDistance(CharSequence pattern) {
    return new Levenshtein(pattern);
  }

  private GeneralEditDistances() { }
}
