use super::revcomp::reverse_complement;
use anyhow::Result;
use lexical_sort::{natural_lexical_cmp, StringSort};
use std::cmp::min;
fn minimal_rotation<T: Ord>(s: &[T]) -> usize {
let n = s.len();
let mut i = 0;
let mut j = 1;
loop {
let mut k = 0;
let mut ci = &s[i % n];
let mut cj = &s[j % n];
while k < n {
ci = &s[(i + k) % n];
cj = &s[(j + k) % n];
if ci != cj {
break;
}
k += 1
}
if k == n {
return min(i, j);
}
if ci > cj {
i += k + 1;
i += (i == j) as usize;
} else {
j += k + 1;
j += (i == j) as usize;
}
}
}
pub fn lex_min(dna_string: &[u8]) -> Result<String> {
let dna_string_r = reverse_complement(dna_string);
let index_f = minimal_rotation(dna_string);
let index_r = minimal_rotation(&dna_string_r);
let start_f = &dna_string[index_f..];
let start_r = &dna_string_r[index_r..];
let end_f = &dna_string[0..index_f];
let end_r = &dna_string_r[0..index_r];
let f = String::from_utf8([start_f, end_f].concat())?;
let r = String::from_utf8([start_r, end_r].concat())?;
let mut strings = [&f, &r];
strings.string_sort_unstable(natural_lexical_cmp);
Ok(strings[0].to_string())
}