//! Checks for needless boolean results of if-else expressions
//!
//! This lint is **warn** by default

use rustc::lint::*;
use rustc::hir::*;
use syntax::ast::LitKind;
use syntax::codemap::Spanned;
use utils::{span_lint, span_lint_and_then, snippet};
use utils::sugg::Sugg;

/// **What it does:** Checks for expressions of the form `if c { true } else { false }`
/// (or vice versa) and suggest using the condition directly.
///
/// **Why is this bad?** Redundant code.
///
/// **Known problems:** Maybe false positives: Sometimes, the two branches are
/// painstakingly documented (which we of course do not detect), so they *may*
/// have some value. Even then, the documentation can be rewritten to match the
/// shorter code.
///
/// **Example:**
/// ```rust
/// if x { false } else { true }
/// ```
declare_lint! {
    pub NEEDLESS_BOOL,
    Warn,
    "if-statements with plain booleans in the then- and else-clause, e.g. \
     `if p { true } else { false }`"
}

/// **What it does:** Checks for expressions of the form `x == true` (or vice
/// versa) and suggest using the variable directly.
///
/// **Why is this bad?** Unnecessary code.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// if x == true { }  // could be `if x { }`
/// ```
declare_lint! {
    pub BOOL_COMPARISON,
    Warn,
    "comparing a variable to a boolean, e.g. `if x == true`"
}

#[derive(Copy,Clone)]
pub struct NeedlessBool;

impl LintPass for NeedlessBool {
    fn get_lints(&self) -> LintArray {
        lint_array!(NEEDLESS_BOOL)
    }
}

impl LateLintPass for NeedlessBool {
    fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
        use self::Expression::*;
        if let ExprIf(ref pred, ref then_block, Some(ref else_expr)) = e.node {
            let reduce = |ret, not| {
                let snip = Sugg::hir(cx, pred, "<predicate>");
                let snip = if not {
                    !snip
                } else {
                    snip
                };

                let hint = if ret {
                    format!("return {}", snip)
                } else {
                    snip.to_string()
                };

                span_lint_and_then(cx,
                                   NEEDLESS_BOOL,
                                   e.span,
                                   "this if-then-else expression returns a bool literal",
                                   |db| {
                                       db.span_suggestion(e.span, "you can reduce it to", hint);
                                   });
            };
            match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) {
                (RetBool(true), RetBool(true)) |
                (Bool(true), Bool(true)) => {
                    span_lint(cx,
                              NEEDLESS_BOOL,
                              e.span,
                              "this if-then-else expression will always return true");
                }
                (RetBool(false), RetBool(false)) |
                (Bool(false), Bool(false)) => {
                    span_lint(cx,
                              NEEDLESS_BOOL,
                              e.span,
                              "this if-then-else expression will always return false");
                }
                (RetBool(true), RetBool(false)) => reduce(true, false),
                (Bool(true), Bool(false)) => reduce(false, false),
                (RetBool(false), RetBool(true)) => reduce(true, true),
                (Bool(false), Bool(true)) => reduce(false, true),
                _ => (),
            }
        }
    }
}

#[derive(Copy,Clone)]
pub struct BoolComparison;

impl LintPass for BoolComparison {
    fn get_lints(&self) -> LintArray {
        lint_array!(BOOL_COMPARISON)
    }
}

impl LateLintPass for BoolComparison {
    fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
        use self::Expression::*;
        if let ExprBinary(Spanned { node: BiEq, .. }, ref left_side, ref right_side) = e.node {
            match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
                (Bool(true), Other) => {
                    let hint = snippet(cx, right_side.span, "..").into_owned();
                    span_lint_and_then(cx,
                                       BOOL_COMPARISON,
                                       e.span,
                                       "equality checks against true are unnecessary",
                                       |db| {
                                           db.span_suggestion(e.span, "try simplifying it as shown:", hint);
                                       });
                }
                (Other, Bool(true)) => {
                    let hint = snippet(cx, left_side.span, "..").into_owned();
                    span_lint_and_then(cx,
                                       BOOL_COMPARISON,
                                       e.span,
                                       "equality checks against true are unnecessary",
                                       |db| {
                                           db.span_suggestion(e.span, "try simplifying it as shown:", hint);
                                       });
                }
                (Bool(false), Other) => {
                    let hint = Sugg::hir(cx, right_side, "..");
                    span_lint_and_then(cx,
                                       BOOL_COMPARISON,
                                       e.span,
                                       "equality checks against false can be replaced by a negation",
                                       |db| {
                                           db.span_suggestion(e.span, "try simplifying it as shown:", (!hint).to_string());
                                       });
                }
                (Other, Bool(false)) => {
                    let hint = Sugg::hir(cx, left_side, "..");
                    span_lint_and_then(cx,
                                       BOOL_COMPARISON,
                                       e.span,
                                       "equality checks against false can be replaced by a negation",
                                       |db| {
                                           db.span_suggestion(e.span, "try simplifying it as shown:", (!hint).to_string());
                                       });
                }
                _ => (),
            }
        }
    }
}

enum Expression {
    Bool(bool),
    RetBool(bool),
    Other,
}

fn fetch_bool_block(block: &Block) -> Expression {
    match (&*block.stmts, block.expr.as_ref()) {
        (&[], Some(e)) => fetch_bool_expr(&**e),
        (&[ref e], None) => {
            if let StmtSemi(ref e, _) = e.node {
                if let ExprRet(_) = e.node {
                    fetch_bool_expr(&**e)
                } else {
                    Expression::Other
                }
            } else {
                Expression::Other
            }
        }
        _ => Expression::Other,
    }
}

fn fetch_bool_expr(expr: &Expr) -> Expression {
    match expr.node {
        ExprBlock(ref block) => fetch_bool_block(block),
        ExprLit(ref lit_ptr) => {
            if let LitKind::Bool(value) = lit_ptr.node {
                Expression::Bool(value)
            } else {
                Expression::Other
            }
        }
        ExprRet(Some(ref expr)) => {
            match fetch_bool_expr(expr) {
                Expression::Bool(value) => Expression::RetBool(value),
                _ => Expression::Other,
            }
        }
        _ => Expression::Other,
    }
}
