// Copyright (C) 2011 The Android Open Source Project
//
// 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.gerrit.server.util;

import com.google.gerrit.entities.AccessSection;
import com.google.gerrit.server.project.RefPattern;
import java.util.Comparator;
import org.apache.commons.text.similarity.LevenshteinDistance;

/**
 * Order the Ref Pattern by the most specific. This sort is done by:
 *
 * <ul>
 *   <li>1 - The minor value of Levenshtein string distance between the branch name and the regex
 *       string shortest example. A shorter distance is a more specific match.
 *   <li>2 - Finites first, infinities after.
 *   <li>3 - Number of transitions. More transitions is more specific.
 *   <li>4 - Length of the expression text.
 * </ul>
 *
 * Levenshtein distance is a measure of the similarity between two strings. The distance is the
 * number of deletions, insertions, or substitutions required to transform one string into another.
 *
 * <p>For example, if given refs/heads/m* and refs/heads/*, the distances are 5 and 6. It means that
 * refs/heads/m* is more specific because it's closer to refs/heads/master than refs/heads/*.
 *
 * <p>Another example could be refs/heads/* and refs/heads/[a-zA-Z]*, the distances are both 6. Both
 * are infinite, but refs/heads/[a-zA-Z]* has more transitions, which after all turns it more
 * specific.
 */
public final class MostSpecificComparator implements Comparator<AccessSection> {
  private final String refName;

  public MostSpecificComparator(String refName) {
    this.refName = refName;
  }

  @Override
  public int compare(AccessSection a, AccessSection b) {
    return compare(a.getName(), b.getName());
  }

  public int compare(String pattern1, String pattern2) {
    int cmp = distance(pattern1) - distance(pattern2);
    if (cmp == 0) {
      boolean p1_finite = finite(pattern1);
      boolean p2_finite = finite(pattern2);

      if (p1_finite && !p2_finite) {
        cmp = -1;
      } else if (!p1_finite && p2_finite) {
        cmp = 1;
      } else /* if (f1 == f2) */ {
        cmp = 0;
      }
    }
    if (cmp == 0) {
      cmp = transitions(pattern2) - transitions(pattern1);
    }
    if (cmp == 0) {
      cmp = pattern2.length() - pattern1.length();
    }
    return cmp;
  }

  private int distance(String pattern) {
    String example;
    if (RefPattern.isRE(pattern)) {
      example = RefPattern.shortestExample(pattern);

    } else if (pattern.endsWith("/*")) {
      example = pattern;

    } else if (pattern.equals(refName)) {
      return 0;

    } else {
      return Math.max(pattern.length(), refName.length());
    }
    return LevenshteinDistance.getDefaultInstance().apply(example, refName);
  }

  private boolean finite(String pattern) {
    if (RefPattern.isRE(pattern)) {
      return RefPattern.toRegExp(pattern).toAutomaton().isFinite();

    } else if (pattern.endsWith("/*")) {
      return false;

    } else {
      return true;
    }
  }

  private int transitions(String pattern) {
    if (RefPattern.isRE(pattern)) {
      return RefPattern.toRegExp(pattern).toAutomaton().getNumberOfTransitions();

    } else if (pattern.endsWith("/*")) {
      return pattern.length();

    } else {
      return pattern.length();
    }
  }
}
