use crate::Token;
use crate::expr::Expr;
use crate::expr::SequenceExpr;

use super::{ExprLinter, Lint, LintKind, Suggestion};
use crate::linting::expr_linter::Chunk;

pub struct LeftRightHand {
    expr: SequenceExpr,
}

impl Default for LeftRightHand {
    fn default() -> Self {
        let pattern = SequenceExpr::word_set(&["left", "right"])
            .then_whitespace()
            .t_aco("hand")
            .then_whitespace()
            .then_noun();

        Self { expr: pattern }
    }
}

impl ExprLinter for LeftRightHand {
    type Unit = Chunk;

    fn expr(&self) -> &dyn Expr {
        &self.expr
    }

    fn match_to_lint(&self, matched_tokens: &[Token], _source: &[char]) -> Option<Lint> {
        let space = &matched_tokens[1];

        Some(Lint {
            span: space.span,
            lint_kind: LintKind::Miscellaneous,
            suggestions: vec![Suggestion::ReplaceWith(vec!['-'])],
            message: "Use a hyphen in `left-hand` or `right-hand` when modifying a noun."
                .to_owned(),
            priority: 31,
        })
    }

    fn description(&self) -> &'static str {
        "Ensures `left hand` and `right hand` are hyphenated when used as adjectives before a noun, such as in `left-hand side` or `right-hand corner`."
    }
}

#[cfg(test)]
mod tests {
    use super::LeftRightHand;
    use crate::linting::tests::assert_suggestion_result;

    #[test]
    fn corrects_left_hand_side() {
        assert_suggestion_result(
            "You'll see it on the left hand side.",
            LeftRightHand::default(),
            "You'll see it on the left-hand side.",
        );
    }

    #[test]
    fn corrects_right_hand_corner() {
        assert_suggestion_result(
            "It's in the right hand corner.",
            LeftRightHand::default(),
            "It's in the right-hand corner.",
        );
    }

    #[test]
    fn does_not_correct_noun_usage() {
        assert_suggestion_result(
            "She raised her right hand.",
            LeftRightHand::default(),
            "She raised her right hand.",
        );
    }
}
