use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::{path_local, path_std};
use rustc_ast::ptr::P;
use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
use thin_vec::thin_vec;

pub(crate) fn expand_deriving_partial_eq(
    cx: &ExtCtxt<'_>,
    span: Span,
    mitem: &MetaItem,
    item: &Annotatable,
    push: &mut dyn FnMut(Annotatable),
    is_const: bool,
) {
    fn cs_eq(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
        let base = true;
        let expr = cs_fold(
            true, // use foldl
            cx,
            span,
            substr,
            |cx, fold| match fold {
                CsFold::Single(field) => {
                    let [other_expr] = &field.other_selflike_exprs[..] else {
                        cx.dcx()
                            .span_bug(field.span, "not exactly 2 arguments in `derive(PartialEq)`");
                    };

                    // We received arguments of type `&T`. Convert them to type `T` by stripping
                    // any leading `&` or adding `*`. This isn't necessary for type checking, but
                    // it results in better error messages if something goes wrong.
                    //
                    // Note: for arguments that look like `&{ x }`, which occur with packed
                    // structs, this would cause expressions like `{ self.x } == { other.x }`,
                    // which isn't valid Rust syntax. This wouldn't break compilation because these
                    // AST nodes are constructed within the compiler. But it would mean that code
                    // printed by `-Zunpretty=expanded` (or `cargo expand`) would have invalid
                    // syntax, which would be suboptimal. So we wrap these in parens, giving
                    // `({ self.x }) == ({ other.x })`, which is valid syntax.
                    let convert = |expr: &P<Expr>| {
                        if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) =
                            &expr.kind
                        {
                            if let ExprKind::Block(..) = &inner.kind {
                                // `&{ x }` form: remove the `&`, add parens.
                                cx.expr_paren(field.span, inner.clone())
                            } else {
                                // `&x` form: remove the `&`.
                                inner.clone()
                            }
                        } else {
                            // No leading `&`: add a leading `*`.
                            cx.expr_deref(field.span, expr.clone())
                        }
                    };
                    cx.expr_binary(
                        field.span,
                        BinOpKind::Eq,
                        convert(&field.self_expr),
                        convert(other_expr),
                    )
                }
                CsFold::Combine(span, expr1, expr2) => {
                    cx.expr_binary(span, BinOpKind::And, expr1, expr2)
                }
                CsFold::Fieldless => cx.expr_bool(span, base),
            },
        );
        BlockOrExpr::new_expr(expr)
    }

    let structural_trait_def = TraitDef {
        span,
        path: path_std!(marker::StructuralPartialEq),
        skip_path_as_bound: true, // crucial!
        needs_copy_as_bound_if_packed: false,
        additional_bounds: Vec::new(),
        // We really don't support unions, but that's already checked by the impl generated below;
        // a second check here would lead to redundant error messages.
        supports_unions: true,
        methods: Vec::new(),
        associated_types: Vec::new(),
        is_const: false,
    };
    structural_trait_def.expand(cx, mitem, item, push);

    // No need to generate `ne`, the default suffices, and not generating it is
    // faster.
    let methods = vec![MethodDef {
        name: sym::eq,
        generics: Bounds::empty(),
        explicit_self: true,
        nonself_args: vec![(self_ref(), sym::other)],
        ret_ty: Path(path_local!(bool)),
        attributes: thin_vec![cx.attr_word(sym::inline, span)],
        fieldless_variants_strategy: FieldlessVariantsStrategy::Unify,
        combine_substructure: combine_substructure(Box::new(|a, b, c| cs_eq(a, b, c))),
    }];

    let trait_def = TraitDef {
        span,
        path: path_std!(cmp::PartialEq),
        skip_path_as_bound: false,
        needs_copy_as_bound_if_packed: true,
        additional_bounds: Vec::new(),
        supports_unions: false,
        methods,
        associated_types: Vec::new(),
        is_const,
    };
    trait_def.expand(cx, mitem, item, push)
}
