use clippy_utils::{
    diagnostics::span_lint_and_then, is_diag_item_method, is_trait_method, match_def_path, path_to_local_id, paths,
    ty::match_type,
};
use rustc_errors::Applicability;
use rustc_hir::{Body, Closure, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;

declare_clippy_lint! {
    /// ### What it does
    /// Checks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)`
    /// when `lines` has type `std::io::Lines`.
    ///
    /// ### Why is this bad?
    /// `Lines` instances might produce a never-ending stream of `Err`, in which case
    /// `filter_map(Result::ok)` will enter an infinite loop while waiting for an
    /// `Ok` variant. Calling `next()` once is sufficient to enter the infinite loop,
    /// even in the absence of explicit loops in the user code.
    ///
    /// This situation can arise when working with user-provided paths. On some platforms,
    /// `std::fs::File::open(path)` might return `Ok(fs)` even when `path` is a directory,
    /// but any later attempt to read from `fs` will return an error.
    ///
    /// ### Known problems
    /// This lint suggests replacing `filter_map()` or `flat_map()` applied to a `Lines`
    /// instance in all cases. There two cases where the suggestion might not be
    /// appropriate or necessary:
    ///
    /// - If the `Lines` instance can never produce any error, or if an error is produced
    ///   only once just before terminating the iterator, using `map_while()` is not
    ///   necessary but will not do any harm.
    /// - If the `Lines` instance can produce intermittent errors then recover and produce
    ///   successful results, using `map_while()` would stop at the first error.
    ///
    /// ### Example
    /// ```rust
    /// # use std::{fs::File, io::{self, BufRead, BufReader}};
    /// # let _ = || -> io::Result<()> {
    /// let mut lines = BufReader::new(File::open("some-path")?).lines().filter_map(Result::ok);
    /// // If "some-path" points to a directory, the next statement never terminates:
    /// let first_line: Option<String> = lines.next();
    /// # Ok(()) };
    /// ```
    /// Use instead:
    /// ```rust
    /// # use std::{fs::File, io::{self, BufRead, BufReader}};
    /// # let _ = || -> io::Result<()> {
    /// let mut lines = BufReader::new(File::open("some-path")?).lines().map_while(Result::ok);
    /// let first_line: Option<String> = lines.next();
    /// # Ok(()) };
    /// ```
    #[clippy::version = "1.70.0"]
    pub LINES_FILTER_MAP_OK,
    suspicious,
    "filtering `std::io::Lines` with `filter_map()` or `flat_map()` might cause an infinite loop"
}
declare_lint_pass!(LinesFilterMapOk => [LINES_FILTER_MAP_OK]);

impl LateLintPass<'_> for LinesFilterMapOk {
    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
        if let ExprKind::MethodCall(fm_method, fm_receiver, [fm_arg], fm_span) = expr.kind &&
            is_trait_method(cx, expr, sym::Iterator) &&
            (fm_method.ident.as_str() == "filter_map" || fm_method.ident.as_str() == "flat_map") &&
            match_type(cx, cx.typeck_results().expr_ty_adjusted(fm_receiver), &paths::STD_IO_LINES)
        {
            let lint = match &fm_arg.kind {
                // Detect `Result::ok`
                ExprKind::Path(qpath) =>
                    cx.qpath_res(qpath, fm_arg.hir_id).opt_def_id().map(|did|
                        match_def_path(cx, did, &paths::CORE_RESULT_OK_METHOD)).unwrap_or_default(),
                // Detect `|x| x.ok()`
                ExprKind::Closure(Closure { body, .. }) =>
                    if let Body { params: [param], value, .. } = cx.tcx.hir().body(*body) &&
                        let ExprKind::MethodCall(method, receiver, [], _) = value.kind &&
                        path_to_local_id(receiver, param.pat.hir_id) &&
                        let Some(method_did) = cx.typeck_results().type_dependent_def_id(value.hir_id)
                    {
                        is_diag_item_method(cx, method_did, sym::Result) && method.ident.as_str() == "ok"
                    } else {
                        false
                    }
                _ => false,
            };
            if lint {
                span_lint_and_then(cx,
                    LINES_FILTER_MAP_OK,
                    fm_span,
                    &format!("`{}()` will run forever if the iterator repeatedly produces an `Err`", fm_method.ident),
                    |diag| {
                        diag.span_note(
                            fm_receiver.span,
                            "this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error");
                        diag.span_suggestion(fm_span, "replace with", "map_while(Result::ok)", Applicability::MaybeIncorrect);
                    });
                }
        }
    }
}
