///|
/// Selects one of the package's supported phonetic encoders.
pub(all) enum Algorithm {
  Soundex
  RefinedSoundex
  Nysiis
  Metaphone
  DoubleMetaphone
  Caverphone1
  Caverphone2
  MatchRating
} derive(Eq, Debug)

///|
/// Encodes an input with the selected algorithm.
pub fn encode(input : String, algorithm : Algorithm) -> String {
  match algorithm {
    Soundex => soundex(input)
    RefinedSoundex => refined_soundex(input)
    Nysiis => nysiis(input)
    Metaphone => metaphone(input)
    DoubleMetaphone => double_metaphone(input).primary
    Caverphone1 => caverphone1(input)
    Caverphone2 => caverphone2(input)
    MatchRating => match_rating_codex(input)
  }
}

///|
/// Compares non-empty phonetic keys produced by the selected algorithm.
pub fn is_match(left : String, right : String, algorithm : Algorithm) -> Bool {
  if algorithm == DoubleMetaphone {
    let left_keys = double_metaphone(left).all_non_empty_keys()
    let right_keys = double_metaphone(right).all_non_empty_keys()
    for left_key in left_keys {
      for right_key in right_keys {
        if left_key == right_key {
          return true
        }
      }
    }
    return false
  }
  let left_key = encode(left, algorithm)
  let right_key = encode(right, algorithm)
  left_key.length() > 0 && right_key.length() > 0 && left_key == right_key
}

///|
/// Encodes every input in order with the selected algorithm.
pub fn encode_all(
  inputs : Array[String],
  algorithm : Algorithm,
) -> Array[String] {
  let output : Array[String] = []
  for input in inputs {
    output.push(encode(input, algorithm))
  }
  output
}