use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
use clippy_utils::higher::{VecInitKind, get_vec_init_kind};
use clippy_utils::source::{indent_of, snippet};
use clippy_utils::{get_enclosing_block, sym};

use rustc_errors::Applicability;
use rustc_hir::def::Res;
use rustc_hir::intravisit::{Visitor, walk_expr};
use rustc_hir::{self as hir, Expr, ExprKind, HirId, LetStmt, PatKind, PathSegment, QPath, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass;

declare_clippy_lint! {
    /// ### What it does
    /// This lint catches reads into a zero-length `Vec`.
    /// Especially in the case of a call to `with_capacity`, this lint warns that read
    /// gets the number of bytes from the `Vec`'s length, not its capacity.
    ///
    /// ### Why is this bad?
    /// Reading zero bytes is almost certainly not the intended behavior.
    ///
    /// ### Known problems
    /// In theory, a very unusual read implementation could assign some semantic meaning
    /// to zero-byte reads. But it seems exceptionally unlikely that code intending to do
    /// a zero-byte read would allocate a `Vec` for it.
    ///
    /// ### Example
    /// ```no_run
    /// use std::io;
    /// fn foo<F: io::Read>(mut f: F) {
    ///     let mut data = Vec::with_capacity(100);
    ///     f.read(&mut data).unwrap();
    /// }
    /// ```
    /// Use instead:
    /// ```no_run
    /// use std::io;
    /// fn foo<F: io::Read>(mut f: F) {
    ///     let mut data = Vec::with_capacity(100);
    ///     data.resize(100, 0);
    ///     f.read(&mut data).unwrap();
    /// }
    /// ```
    #[clippy::version = "1.63.0"]
    pub READ_ZERO_BYTE_VEC,
    nursery,
    "checks for reads into a zero-length `Vec`"
}

declare_lint_pass!(ReadZeroByteVec => [READ_ZERO_BYTE_VEC]);

impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &hir::Block<'tcx>) {
        for stmt in block.stmts {
            if stmt.span.from_expansion() {
                return;
            }

            if let StmtKind::Let(local) = stmt.kind
                && let LetStmt {
                    pat, init: Some(init), ..
                } = local
                && let PatKind::Binding(_, id, ident, _) = pat.kind
                && let Some(vec_init_kind) = get_vec_init_kind(cx, init)
            {
                let mut visitor = ReadVecVisitor {
                    local_id: id,
                    read_zero_expr: None,
                    has_resize: false,
                };

                let Some(enclosing_block) = get_enclosing_block(cx, id) else {
                    return;
                };
                visitor.visit_block(enclosing_block);

                if let Some(expr) = visitor.read_zero_expr {
                    let applicability = Applicability::MaybeIncorrect;
                    match vec_init_kind {
                        VecInitKind::WithConstCapacity(len) => span_lint_hir_and_then(
                            cx,
                            READ_ZERO_BYTE_VEC,
                            expr.hir_id,
                            expr.span,
                            "reading zero byte data to `Vec`",
                            |diag| {
                                let span = first_stmt_containing_expr(cx, expr).map_or(expr.span, |stmt| stmt.span);
                                let indent = indent_of(cx, span).unwrap_or(0);
                                diag.span_suggestion(
                                    span.shrink_to_lo(),
                                    "try",
                                    format!("{ident}.resize({len}, 0);\n{}", " ".repeat(indent)),
                                    applicability,
                                );
                            },
                        ),
                        VecInitKind::WithExprCapacity(hir_id) => {
                            let e = cx.tcx.hir_expect_expr(hir_id);
                            span_lint_hir_and_then(
                                cx,
                                READ_ZERO_BYTE_VEC,
                                expr.hir_id,
                                expr.span,
                                "reading zero byte data to `Vec`",
                                |diag| {
                                    let span = first_stmt_containing_expr(cx, expr).map_or(expr.span, |stmt| stmt.span);
                                    let indent = indent_of(cx, span).unwrap_or(0);
                                    diag.span_suggestion(
                                        span.shrink_to_lo(),
                                        "try",
                                        format!(
                                            "{ident}.resize({}, 0);\n{}",
                                            snippet(cx, e.span, ".."),
                                            " ".repeat(indent)
                                        ),
                                        applicability,
                                    );
                                },
                            );
                        },
                        _ => {
                            span_lint_hir(
                                cx,
                                READ_ZERO_BYTE_VEC,
                                expr.hir_id,
                                expr.span,
                                "reading zero byte data to `Vec`",
                            );
                        },
                    }
                }
            }
        }
    }
}

fn first_stmt_containing_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx hir::Stmt<'tcx>> {
    cx.tcx.hir_parent_iter(expr.hir_id).find_map(|(_, node)| {
        if let hir::Node::Stmt(stmt) = node {
            Some(stmt)
        } else {
            None
        }
    })
}

struct ReadVecVisitor<'tcx> {
    local_id: HirId,
    read_zero_expr: Option<&'tcx Expr<'tcx>>,
    has_resize: bool,
}

impl<'tcx> Visitor<'tcx> for ReadVecVisitor<'tcx> {
    fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) {
        if let ExprKind::MethodCall(path, receiver, args, _) = e.kind {
            let PathSegment { ident, .. } = *path;

            match ident.name {
                sym::read | sym::read_exact => {
                    let [arg] = args else { return };
                    if let ExprKind::AddrOf(_, hir::Mutability::Mut, inner) = arg.kind
                        && let ExprKind::Path(QPath::Resolved(None, inner_path)) = inner.kind
                        && let [inner_seg] = inner_path.segments
                        && let Res::Local(res_id) = inner_seg.res
                        && self.local_id == res_id
                    {
                        self.read_zero_expr = Some(e);
                        return;
                    }
                },
                sym::resize => {
                    // If the Vec is resized, then it's a valid read
                    if let ExprKind::Path(QPath::Resolved(_, inner_path)) = receiver.kind
                        && let Res::Local(res_id) = inner_path.res
                        && self.local_id == res_id
                    {
                        self.has_resize = true;
                        return;
                    }
                },
                _ => {},
            }
        }

        if !self.has_resize && self.read_zero_expr.is_none() {
            walk_expr(self, e);
        }
    }
}
