// SPDX-FileCopyrightText: 2023 Gleb Smirnov glebsmirnov0708@gmail.com
//
// SPDX-License-Identifier: GPL-3.0-or-later

use crate::utils::ActionModel;

/// Calculates irrelevance for a list of fields.
///
/// This function gets a list of fields
/// and a search query and returns fields'
/// search irrelevance.
///
/// Returns [`u16::MAX`] if the fields don't match the query.
fn irrelevance(fields: &[&str], query: &str) -> u16 {
    // If the query is empty, everything is equally relevant
    if query.is_empty() {
        return 0;
    }

    // Initial irrelevance is always zero
    let mut irrelevance = 0;

    let mut field_starts = vec![0; fields.len()];

    // Each word (term) of the query is processed separately
    for term in query.split_whitespace() {
        // Find the first field that matches the term
        let matching_field = fields
            .iter()
            .enumerate()
            .map(|(i, field)| (i, &field[field_starts[i]..]))
            .find_map(|(i, field)| Some((i, field.find(term)?)));

        match matching_field {
            // None of fields mathes the term,
            None => return u16::MAX,
            Some((i, match_index)) => {
                // Increase irrelevance by number of skipped characters
                irrelevance += match_index as u16;
                // Cut the field
                field_starts[i] += match_index + term.len();
            }
        }
    }

    // Increase irrelevance by sum of lengths
    // of leading non-matched fields
    irrelevance += (0..fields.len())
        .take_while(|&i| field_starts[i] == 0)
        .map(|i| fields[i].len() as u16)
        .sum::<u16>();

    irrelevance
}

/// Calculates irrelevance for action.
pub fn action_irrelevance(action: &ActionModel, query: &str) -> u16 {
    let lowercase_query = query.to_lowercase();

    u16::min(
        // Irrelevance of non-translated action info
        irrelevance(
            &[
                &action.name().to_lowercase(),
                &action.description().to_lowercase(),
            ],
            &lowercase_query,
        ),
        // Irrelevance of translated action info
        irrelevance(
            &[
                &action.translated_name().to_lowercase(),
                &action.translated_description().to_lowercase(),
            ],
            &lowercase_query,
        ),
    )
}
