use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::snippet;
use clippy_utils::ty::is_copy;
use clippy_utils::{get_parent_expr, is_mutable};
use rustc_hir::{Expr, ExprField, ExprKind, Path, QPath, StructTailExpr, UnOp};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass;
use rustc_span::{DesugaringKind, Ident};

declare_clippy_lint! {
    /// ### What it does
    /// Checks for initialization of an identical `struct` from another instance
    /// of the type, either by copying a base without setting any field or by
    /// moving all fields individually.
    ///
    /// ### Why is this bad?
    /// Readability suffers from unnecessary struct building.
    ///
    /// ### Example
    /// ```no_run
    /// struct S { s: String }
    ///
    /// let a = S { s: String::from("Hello, world!") };
    /// let b = S { ..a };
    /// ```
    /// Use instead:
    /// ```no_run
    /// struct S { s: String }
    ///
    /// let a = S { s: String::from("Hello, world!") };
    /// let b = a;
    /// ```
    ///
    /// The struct literal ``S { ..a }`` in the assignment to ``b`` could be replaced
    /// with just ``a``.
    ///
    /// ### Known Problems
    /// Has false positives when the base is a place expression that cannot be
    /// moved out of, see [#10547](https://github.com/rust-lang/rust-clippy/issues/10547).
    ///
    /// Empty structs are ignored by the lint.
    #[clippy::version = "1.70.0"]
    pub UNNECESSARY_STRUCT_INITIALIZATION,
    nursery,
    "struct built from a base that can be written mode concisely"
}

declare_lint_pass!(UnnecessaryStruct => [UNNECESSARY_STRUCT_INITIALIZATION]);

impl LateLintPass<'_> for UnnecessaryStruct {
    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
        let ExprKind::Struct(_, fields, base) = expr.kind else {
            return;
        };

        let expr_span = expr.range_span().unwrap_or(expr.span);
        if expr_span.from_expansion() {
            // Prevent lint from hitting inside macro code
            return;
        }

        let field_path = same_path_in_all_fields(cx, expr, fields);

        let sugg = match (field_path, base) {
            (Some(&path), StructTailExpr::None | StructTailExpr::DefaultFields(_)) => {
                // all fields match, no base given
                path.span
            },
            (Some(path), StructTailExpr::Base(base))
                if base_is_suitable(cx, expr, base) && path_matches_base(path, base) =>
            {
                // all fields match, has base: ensure that the path of the base matches
                base.span
            },
            (None, StructTailExpr::Base(base)) if fields.is_empty() && base_is_suitable(cx, expr, base) => {
                // just the base, no explicit fields
                base.span
            },
            _ => return,
        };

        span_lint_and_sugg(
            cx,
            UNNECESSARY_STRUCT_INITIALIZATION,
            expr_span,
            "unnecessary struct building",
            "replace with",
            snippet(cx, sugg, "..").into_owned(),
            rustc_errors::Applicability::MachineApplicable,
        );
    }
}

fn base_is_suitable(cx: &LateContext<'_>, expr: &Expr<'_>, base: &Expr<'_>) -> bool {
    if !check_references(cx, expr, base) {
        return false;
    }

    // TODO: do not propose to replace *XX if XX is not Copy
    if let ExprKind::Unary(UnOp::Deref, target) = base.kind
        && matches!(target.kind, ExprKind::Path(..))
        && !is_copy(cx, cx.typeck_results().expr_ty(expr))
    {
        // `*base` cannot be used instead of the struct in the general case if it is not Copy.
        return false;
    }
    true
}

/// Check whether all fields of a struct assignment match.
/// Returns a [Path] item that one can obtain a span from for the lint suggestion.
///
/// Conditions that must be satisfied to trigger this variant of the lint:
///
/// - source struct of the assignment must be of same type as the destination
/// - names of destination struct fields must match the field names of the source
///
/// We don’t check here if all struct fields are assigned as the remainder may
/// be filled in from a base struct.
fn same_path_in_all_fields<'tcx>(
    cx: &LateContext<'_>,
    expr: &Expr<'_>,
    fields: &[ExprField<'tcx>],
) -> Option<&'tcx Path<'tcx>> {
    let ty = cx.typeck_results().expr_ty(expr);

    let mut found = None;

    for f in fields {
        // fields are assigned from expression
        if let ExprKind::Field(src_expr, ident) = f.expr.kind
            // expression type matches
            && ty == cx.typeck_results().expr_ty(src_expr)
            // field name matches
            && ident_without_range_desugaring(f.ident) == ident
            // assigned from a path expression
            && let ExprKind::Path(QPath::Resolved(None, src_path)) = src_expr.kind
        {
            let Some((_, p)) = found else {
                // this is the first field assignment in the list
                found = Some((src_expr, src_path));
                continue;
            };

            if p.res == src_path.res {
                // subsequent field assignment with same origin struct as before
                continue;
            }
        }
        // source of field assignment doesn’t qualify
        return None;
    }

    if let Some((src_expr, src_path)) = found
        && check_references(cx, expr, src_expr)
    {
        Some(src_path)
    } else {
        None
    }
}

fn check_references(cx: &LateContext<'_>, expr_a: &Expr<'_>, expr_b: &Expr<'_>) -> bool {
    if let Some(parent) = get_parent_expr(cx, expr_a)
        && let parent_ty = cx.typeck_results().expr_ty_adjusted(parent)
        && parent_ty.is_any_ptr()
    {
        if is_copy(cx, cx.typeck_results().expr_ty(expr_a)) && expr_b.res_local_id().is_some() {
            // When the type implements `Copy`, a reference to the new struct works on the
            // copy. Using the original would borrow it.
            return false;
        }

        if parent_ty.is_mutable_ptr() && !is_mutable(cx, expr_b) {
            // The original can be used in a mutable reference context only if it is mutable.
            return false;
        }
    }

    true
}

/// When some fields are assigned from a base struct and others individually
/// the lint applies only if the source of the field is the same as the base.
/// This is enforced here by comparing the path of the base expression;
/// needless to say the lint only applies if it (or whatever expression it is
/// a reference of) actually has a path.
fn path_matches_base(path: &Path<'_>, base: &Expr<'_>) -> bool {
    let base_path = match base.kind {
        ExprKind::Unary(UnOp::Deref, base_expr) => {
            if let ExprKind::Path(QPath::Resolved(_, base_path)) = base_expr.kind {
                base_path
            } else {
                return false;
            }
        },
        ExprKind::Path(QPath::Resolved(_, base_path)) => base_path,
        _ => return false,
    };
    path.res == base_path.res
}

fn ident_without_range_desugaring(ident: Ident) -> Ident {
    if ident.span.desugaring_kind() == Some(DesugaringKind::RangeExpr) {
        Ident {
            span: ident.span.parent_callsite().unwrap(),
            ..ident
        }
    } else {
        ident
    }
}
