use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_from_proc_macro;
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_span::sym;

use super::ITER_SKIP_ZERO;

pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg_expr: &Expr<'_>) {
    if !expr.span.from_expansion()
        && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)
        && let Some(arg) = ConstEvalCtxt::new(cx)
            .eval_local(arg_expr, expr.span.ctxt())
            .and_then(|constant| {
                if let Constant::Int(arg) = constant {
                    Some(arg)
                } else {
                    None
                }
            })
        && arg == 0
        && !is_from_proc_macro(cx, expr)
    {
        span_lint_and_then(cx, ITER_SKIP_ZERO, arg_expr.span, "usage of `.skip(0)`", |diag| {
            diag.span_suggestion(
                arg_expr.span,
                "if you meant to skip the first element, use",
                "1",
                Applicability::MaybeIncorrect,
            )
            .note("this call to `skip` does nothing and is useless; remove it");
        });
    }
}
