package dokerplp.bot.utli

import java.util.*

/*
Code was taken from
https://stackoverflow.com/questions/955110/similarity-string-comparison-in-java
 */

/**
 * Calculates the similarity (a number within 0 and 1) between two strings.
 */
fun stringSimilarity(s1: String, s2: String): Double {
  var longer = s1
  var shorter = s2
  if (s1.length < s2.length) { // longer should always have greater length
    longer = s2
    shorter = s1
  }
  val longerLength = longer.length
  return if (longerLength == 0) {
    1.0 /* both strings are zero length */
  } else (longerLength - editDistance(longer, shorter)) / longerLength.toDouble()
  /* // If you have Apache Commons Text, you can use it to calculate the edit distance:
  LevenshteinDistance levenshteinDistance = new LevenshteinDistance();
  return (longerLength - levenshteinDistance.apply(longer, shorter)) / (double) longerLength; */
}

// Example implementation of the Levenshtein Edit Distance
// See http://rosettacode.org/wiki/Levenshtein_distance#Java
private fun editDistance(s1: String, s2: String): Int {
  var s1 = s1
  var s2 = s2
  s1 = s1.lowercase(Locale.getDefault())
  s2 = s2.lowercase(Locale.getDefault())
  val costs = IntArray(s2.length + 1)
  for (i in 0..s1.length) {
    var lastValue = i
    for (j in 0..s2.length) {
      if (i == 0) costs[j] = j else {
        if (j > 0) {
          var newValue = costs[j - 1]
          if (s1[i - 1] != s2[j - 1]) newValue = Math.min(
            Math.min(newValue, lastValue),
            costs[j]
          ) + 1
          costs[j - 1] = lastValue
          lastValue = newValue
        }
      }
    }
    if (i > 0) costs[s2.length] = lastValue
  }
  return costs[s2.length]
}