use std::borrow::Cow;

use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::SpanExt as _;
use rustc_errors::Applicability;
use rustc_hir::{Expr, GenericArg, HirId, LetStmt, Node, Path, TyKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty};
use rustc_span::Span;

use crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS;

fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) -> Option<LetStmt<'tcx>> {
    let mut parent_iter = cx.tcx.hir_parent_iter(expr_hir_id);
    if let Some((_, node)) = parent_iter.next() {
        match node {
            Node::LetStmt(local) => Some(*local),
            Node::Block(_) => {
                if let Some((parent_hir_id, Node::Expr(expr))) = parent_iter.next()
                    && matches!(expr.kind, rustc_hir::ExprKind::Block(_, _))
                {
                    get_parent_local_binding_ty(cx, parent_hir_id)
                } else {
                    None
                }
            },
            _ => None,
        }
    } else {
        None
    }
}

fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool {
    let def_id = cx.tcx.hir_enclosing_body_owner(expr_hir_id);
    if let Some(body) = cx.tcx.hir_maybe_body_owned_by(def_id) {
        return body.value.peel_blocks().hir_id == expr_hir_id;
    }
    false
}

pub(super) fn check<'tcx>(
    cx: &LateContext<'tcx>,
    path: &Path<'tcx>,
    arg: &Expr<'tcx>,
    from_ty: Ty<'tcx>,
    to_ty: Ty<'tcx>,
    expr_hir_id: HirId,
) -> bool {
    let last = path.segments.last().unwrap();
    if last.ident.span.in_external_macro(cx.tcx.sess.source_map()) {
        // If it comes from a non-local macro, we ignore it.
        return false;
    }
    let args = last.args;
    let missing_generic = match args {
        Some(args) if !args.args.is_empty() => args.args.iter().any(|arg| matches!(arg, GenericArg::Infer(_))),
        _ => true,
    };
    if !missing_generic {
        return false;
    }
    // If it's being set as a local variable value...
    if let Some(local) = get_parent_local_binding_ty(cx, expr_hir_id) {
        // ... which does have type annotations.
        if let Some(ty) = local.ty
            // If this is a `let x: _ =`, we should lint.
            && !matches!(ty.kind, TyKind::Infer(()))
        {
            return false;
        }
    // We check if this transmute is not the only element in the function
    } else if is_function_block(cx, expr_hir_id) {
        return false;
    }
    let span = last.ident.span.with_hi(path.span.hi());
    span_lint_and_then(
        cx,
        MISSING_TRANSMUTE_ANNOTATIONS,
        span,
        "transmute used without annotations",
        |diag| {
            let from_ty_no_name = ty_cannot_be_named(from_ty);
            let to_ty_no_name = ty_cannot_be_named(to_ty);
            if from_ty_no_name || to_ty_no_name {
                let to_name = match (from_ty_no_name, to_ty_no_name) {
                    (true, false) => maybe_name_by_expr(cx, arg.span, "the origin type"),
                    (false, true) => "the destination type".into(),
                    _ => "the source and destination types".into(),
                };
                diag.help(format!(
                    "consider giving {to_name} a name, and adding missing type annotations"
                ));
            } else {
                diag.span_suggestion(
                    span,
                    "consider adding missing annotations",
                    format!("{}::<{from_ty}, {to_ty}>", last.ident),
                    Applicability::MaybeIncorrect,
                );
            }
        },
    );
    true
}

fn ty_cannot_be_named(ty: Ty<'_>) -> bool {
    matches!(
        ty.kind(),
        ty::Alias(
            _,
            ty::AliasTy {
                kind: ty::Opaque { .. } | ty::Inherent { .. },
                ..
            }
        )
    )
}

fn maybe_name_by_expr<'a>(cx: &LateContext<'_>, span: Span, default: &'a str) -> Cow<'a, str> {
    span.with_source_text(cx, |name| {
        (name.len() + 9 < default.len()).then_some(format!("`{name}`'s type").into())
    })
    .flatten()
    .unwrap_or(default.into())
}
