use std::sync::Arc;

use rustc_ast::{self as ast, *};
use rustc_hir::def::{DefKind, PartialRes, PerNS, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, GenericArg};
use rustc_middle::{span_bug, ty};
use rustc_session::parse::add_feature_diagnostics;
use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, Symbol, sym};
use smallvec::smallvec;
use tracing::{debug, instrument};

use super::errors::{
    AsyncBoundNotOnTrait, AsyncBoundOnlyForFnTraits, BadReturnTypeNotation,
    GenericTypeWithParentheses, RTNSuggestion, UseAngleBrackets,
};
use super::{
    AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, ImplTraitPosition,
    LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt,
};

impl<'a, 'hir> LoweringContext<'a, 'hir> {
    #[instrument(level = "trace", skip(self))]
    pub(crate) fn lower_qpath(
        &mut self,
        id: NodeId,
        qself: &Option<Box<QSelf>>,
        p: &Path,
        param_mode: ParamMode,
        allow_return_type_notation: AllowReturnTypeNotation,
        itctx: ImplTraitContext,
        // modifiers of the impl/bound if this is a trait path
        modifiers: Option<ast::TraitBoundModifiers>,
    ) -> hir::QPath<'hir> {
        let qself_position = qself.as_ref().map(|q| q.position);
        let qself = qself
            .as_ref()
            // Reject cases like `<impl Trait>::Assoc` and `<impl Trait as Trait>::Assoc`.
            .map(|q| {
                self.lower_ty_alloc(&q.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path))
            });

        let partial_res =
            self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err));
        let base_res = partial_res.base_res();
        let unresolved_segments = partial_res.unresolved_segments();

        let mut res = self.lower_res(base_res);

        // When we have an `async` kw on a bound, map the trait it resolves to.
        if let Some(TraitBoundModifiers { asyncness: BoundAsyncness::Async(_), .. }) = modifiers {
            match res {
                Res::Def(DefKind::Trait, def_id) => {
                    if let Some(async_def_id) = self.map_trait_to_async_trait(def_id) {
                        res = Res::Def(DefKind::Trait, async_def_id);
                    } else {
                        self.dcx().emit_err(AsyncBoundOnlyForFnTraits { span: p.span });
                    }
                }
                Res::Err => {
                    // No additional error.
                }
                _ => {
                    // This error isn't actually emitted AFAICT, but it's best to keep
                    // it around in case the resolver doesn't always check the defkind
                    // of an item or something.
                    self.dcx().emit_err(AsyncBoundNotOnTrait { span: p.span, descr: res.descr() });
                }
            }
        }

        // Ungate the `async_fn_traits` feature in the path if the trait is
        // named via either `async Fn*()` or `AsyncFn*()`.
        let bound_modifier_allowed_features = if let Res::Def(DefKind::Trait, async_def_id) = res
            && self.tcx.async_fn_trait_kind_from_def_id(async_def_id).is_some()
        {
            Some(Arc::clone(&self.allow_async_fn_traits))
        } else {
            None
        };

        // Only permit `impl Trait` in the final segment. E.g., we permit `Option<impl Trait>`,
        // `option::Option<T>::Xyz<impl Trait>` and reject `option::Option<impl Trait>::Xyz`.
        let itctx = |i| {
            if i + 1 == p.segments.len() {
                itctx
            } else {
                ImplTraitContext::Disallowed(ImplTraitPosition::Path)
            }
        };

        let path_span_lo = p.span.shrink_to_lo();
        let proj_start = p.segments.len() - unresolved_segments;
        let path = self.arena.alloc(hir::Path {
            res,
            segments: self.arena.alloc_from_iter(p.segments[..proj_start].iter().enumerate().map(
                |(i, segment)| {
                    let param_mode = match (qself_position, param_mode) {
                        (Some(j), ParamMode::Optional) if i < j => {
                            // This segment is part of the trait path in a
                            // qualified path - one of `a`, `b` or `Trait`
                            // in `<X as a::b::Trait>::T::U::method`.
                            ParamMode::Explicit
                        }
                        _ => param_mode,
                    };

                    let generic_args_mode = match base_res {
                        // `a::b::Trait(Args)`
                        Res::Def(DefKind::Trait, _) if i + 1 == proj_start => {
                            GenericArgsMode::ParenSugar
                        }
                        // `a::b::Trait(Args)::TraitItem`
                        Res::Def(DefKind::AssocFn, _)
                        | Res::Def(DefKind::AssocConst, _)
                        | Res::Def(DefKind::AssocTy, _)
                            if i + 2 == proj_start =>
                        {
                            GenericArgsMode::ParenSugar
                        }
                        Res::Def(DefKind::AssocFn, _) if i + 1 == proj_start => {
                            match allow_return_type_notation {
                                AllowReturnTypeNotation::Yes => GenericArgsMode::ReturnTypeNotation,
                                AllowReturnTypeNotation::No => GenericArgsMode::Err,
                            }
                        }
                        // Avoid duplicated errors.
                        Res::Err => GenericArgsMode::Silence,
                        // An error
                        _ => GenericArgsMode::Err,
                    };

                    self.lower_path_segment(
                        p.span,
                        segment,
                        param_mode,
                        generic_args_mode,
                        itctx(i),
                        bound_modifier_allowed_features.clone(),
                    )
                },
            )),
            span: self.lower_span(
                p.segments[..proj_start]
                    .last()
                    .map_or(path_span_lo, |segment| path_span_lo.to(segment.span())),
            ),
        });

        if let Some(bound_modifier_allowed_features) = bound_modifier_allowed_features {
            path.span = self.mark_span_with_reason(
                DesugaringKind::BoundModifier,
                path.span,
                Some(bound_modifier_allowed_features),
            );
        }

        // Simple case, either no projections, or only fully-qualified.
        // E.g., `std::mem::size_of` or `<I as Iterator>::Item`.
        if unresolved_segments == 0 {
            return hir::QPath::Resolved(qself, path);
        }

        // Create the innermost type that we're projecting from.
        let mut ty = if path.segments.is_empty() {
            // If the base path is empty that means there exists a
            // syntactical `Self`, e.g., `&i32` in `<&i32>::clone`.
            qself.expect("missing QSelf for <T>::...")
        } else {
            // Otherwise, the base path is an implicit `Self` type path,
            // e.g., `Vec` in `Vec::new` or `<I as Iterator>::Item` in
            // `<I as Iterator>::Item::default`.
            let new_id = self.next_id();
            self.arena.alloc(self.ty_path(new_id, path.span, hir::QPath::Resolved(qself, path)))
        };

        // Anything after the base path are associated "extensions",
        // out of which all but the last one are associated types,
        // e.g., for `std::vec::Vec::<T>::IntoIter::Item::clone`:
        // * base path is `std::vec::Vec<T>`
        // * "extensions" are `IntoIter`, `Item` and `clone`
        // * type nodes are:
        //   1. `std::vec::Vec<T>` (created above)
        //   2. `<std::vec::Vec<T>>::IntoIter`
        //   3. `<<std::vec::Vec<T>>::IntoIter>::Item`
        // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
        for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
            // If this is a type-dependent `T::method(..)`.
            let generic_args_mode = if i + 1 == p.segments.len()
                && matches!(allow_return_type_notation, AllowReturnTypeNotation::Yes)
            {
                GenericArgsMode::ReturnTypeNotation
            } else {
                GenericArgsMode::Err
            };

            let hir_segment = self.arena.alloc(self.lower_path_segment(
                p.span,
                segment,
                param_mode,
                generic_args_mode,
                itctx(i),
                None,
            ));
            let qpath = hir::QPath::TypeRelative(ty, hir_segment);

            // It's finished, return the extension of the right node type.
            if i == p.segments.len() - 1 {
                return qpath;
            }

            // Wrap the associated extension in another type node.
            let new_id = self.next_id();
            ty = self.arena.alloc(self.ty_path(new_id, path_span_lo.to(segment.span()), qpath));
        }

        // We should've returned in the for loop above.

        self.dcx().span_bug(
            p.span,
            format!(
                "lower_qpath: no final extension segment in {}..{}",
                proj_start,
                p.segments.len()
            ),
        );
    }

    pub(crate) fn lower_use_path(
        &mut self,
        res: PerNS<Option<Res>>,
        p: &Path,
        param_mode: ParamMode,
    ) -> &'hir hir::UsePath<'hir> {
        assert!(!res.is_empty());
        self.arena.alloc(hir::UsePath {
            res,
            segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| {
                self.lower_path_segment(
                    p.span,
                    segment,
                    param_mode,
                    GenericArgsMode::Err,
                    ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                    None,
                )
            })),
            span: self.lower_span(p.span),
        })
    }

    pub(crate) fn lower_path_segment(
        &mut self,
        path_span: Span,
        segment: &PathSegment,
        param_mode: ParamMode,
        generic_args_mode: GenericArgsMode,
        itctx: ImplTraitContext,
        // Additional features ungated with a bound modifier like `async`.
        // This is passed down to the implicit associated type binding in
        // parenthesized bounds.
        bound_modifier_allowed_features: Option<Arc<[Symbol]>>,
    ) -> hir::PathSegment<'hir> {
        debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment);
        let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() {
            match generic_args {
                GenericArgs::AngleBracketed(data) => {
                    self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
                }
                GenericArgs::Parenthesized(data) => match generic_args_mode {
                    GenericArgsMode::ReturnTypeNotation => {
                        let err = match (&data.inputs[..], &data.output) {
                            ([_, ..], FnRetTy::Default(_)) => {
                                BadReturnTypeNotation::Inputs { span: data.inputs_span }
                            }
                            ([], FnRetTy::Default(_)) => {
                                BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
                            }
                            // The case `T: Trait<method(..) -> Ret>` is handled in the parser.
                            (_, FnRetTy::Ty(ty)) => {
                                let span = data.inputs_span.shrink_to_hi().to(ty.span);
                                BadReturnTypeNotation::Output {
                                    span,
                                    suggestion: RTNSuggestion {
                                        output: span,
                                        input: data.inputs_span,
                                    },
                                }
                            }
                        };
                        let mut err = self.dcx().create_err(err);
                        if !self.tcx.features().return_type_notation()
                            && self.tcx.sess.is_nightly_build()
                        {
                            add_feature_diagnostics(
                                &mut err,
                                &self.tcx.sess,
                                sym::return_type_notation,
                            );
                        }
                        err.emit();
                        (
                            GenericArgsCtor {
                                args: Default::default(),
                                constraints: &[],
                                parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
                                span: path_span,
                            },
                            false,
                        )
                    }
                    GenericArgsMode::ParenSugar | GenericArgsMode::Silence => self
                        .lower_parenthesized_parameter_data(
                            data,
                            itctx,
                            bound_modifier_allowed_features,
                        ),
                    GenericArgsMode::Err => {
                        // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
                        let sub = if !data.inputs.is_empty() {
                            // Start of the span to the 1st character of 1st argument
                            let open_param = data.inputs_span.shrink_to_lo().to(data
                                .inputs
                                .first()
                                .unwrap()
                                .span
                                .shrink_to_lo());
                            // Last character position of last argument to the end of the span
                            let close_param = data
                                .inputs
                                .last()
                                .unwrap()
                                .span
                                .shrink_to_hi()
                                .to(data.inputs_span.shrink_to_hi());

                            Some(UseAngleBrackets { open_param, close_param })
                        } else {
                            None
                        };
                        self.dcx().emit_err(GenericTypeWithParentheses { span: data.span, sub });
                        (
                            self.lower_angle_bracketed_parameter_data(
                                &data.as_angle_bracketed_args(),
                                param_mode,
                                itctx,
                            )
                            .0,
                            false,
                        )
                    }
                },
                GenericArgs::ParenthesizedElided(span) => {
                    match generic_args_mode {
                        GenericArgsMode::ReturnTypeNotation | GenericArgsMode::Silence => {
                            // Ok
                        }
                        GenericArgsMode::ParenSugar | GenericArgsMode::Err => {
                            self.dcx().emit_err(BadReturnTypeNotation::Position { span: *span });
                        }
                    }
                    (
                        GenericArgsCtor {
                            args: Default::default(),
                            constraints: &[],
                            parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
                            span: *span,
                        },
                        false,
                    )
                }
            }
        } else {
            (
                GenericArgsCtor {
                    args: Default::default(),
                    constraints: &[],
                    parenthesized: hir::GenericArgsParentheses::No,
                    span: path_span.shrink_to_hi(),
                },
                param_mode == ParamMode::Optional,
            )
        };

        let has_lifetimes =
            generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)));

        // FIXME(return_type_notation): Is this correct? I think so.
        if generic_args.parenthesized != hir::GenericArgsParentheses::ParenSugar && !has_lifetimes {
            self.maybe_insert_elided_lifetimes_in_path(
                path_span,
                segment.id,
                segment.ident.span,
                &mut generic_args,
            );
        }

        let res = self.expect_full_res(segment.id);
        let hir_id = self.lower_node_id(segment.id);
        debug!(
            "lower_path_segment: ident={:?} original-id={:?} new-id={:?}",
            segment.ident, segment.id, hir_id,
        );

        hir::PathSegment {
            ident: self.lower_ident(segment.ident),
            hir_id,
            res: self.lower_res(res),
            infer_args,
            args: if generic_args.is_empty() && generic_args.span.is_empty() {
                None
            } else {
                Some(generic_args.into_generic_args(self))
            },
        }
    }

    fn maybe_insert_elided_lifetimes_in_path(
        &mut self,
        path_span: Span,
        segment_id: NodeId,
        segment_ident_span: Span,
        generic_args: &mut GenericArgsCtor<'hir>,
    ) {
        let (start, end) = match self.resolver.get_lifetime_res(segment_id) {
            Some(LifetimeRes::ElidedAnchor { start, end }) => (start, end),
            None => return,
            Some(res) => {
                span_bug!(path_span, "expected an elided lifetime to insert. found {res:?}")
            }
        };
        let expected_lifetimes = end.as_usize() - start.as_usize();
        debug!(expected_lifetimes);

        // Note: these spans are used for diagnostics when they can't be inferred.
        // See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
        let (elided_lifetime_span, angle_brackets) = if generic_args.span.is_empty() {
            // No brackets, e.g. `Path`: use an empty span just past the end of the identifier.
            // HACK: we use find_ancestor_inside to properly suggest elided spans in paths
            // originating from macros, since the segment's span might be from a macro arg.
            (
                segment_ident_span.find_ancestor_inside(path_span).unwrap_or(path_span),
                hir::AngleBrackets::Missing,
            )
        } else {
            // Brackets, e.g. `Path<>` or `Path<T>`: use an empty span just after the `<`.
            (
                generic_args.span.with_lo(generic_args.span.lo() + BytePos(1)).shrink_to_lo(),
                if generic_args.is_empty() {
                    hir::AngleBrackets::Empty
                } else {
                    hir::AngleBrackets::Full
                },
            )
        };

        generic_args.args.insert_many(
            0,
            (start..end).map(|id| {
                let l =
                    self.lower_lifetime_hidden_in_path(id, elided_lifetime_span, angle_brackets);
                GenericArg::Lifetime(l)
            }),
        );
    }

    pub(crate) fn lower_angle_bracketed_parameter_data(
        &mut self,
        data: &AngleBracketedArgs,
        param_mode: ParamMode,
        itctx: ImplTraitContext,
    ) -> (GenericArgsCtor<'hir>, bool) {
        let has_non_lt_args = data.args.iter().any(|arg| match arg {
            AngleBracketedArg::Arg(ast::GenericArg::Lifetime(_))
            | AngleBracketedArg::Constraint(_) => false,
            AngleBracketedArg::Arg(ast::GenericArg::Type(_) | ast::GenericArg::Const(_)) => true,
        });
        let args = data
            .args
            .iter()
            .filter_map(|arg| match arg {
                AngleBracketedArg::Arg(arg) => Some(self.lower_generic_arg(arg, itctx)),
                AngleBracketedArg::Constraint(_) => None,
            })
            .collect();
        let constraints =
            self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg {
                AngleBracketedArg::Constraint(c) => {
                    Some(self.lower_assoc_item_constraint(c, itctx))
                }
                AngleBracketedArg::Arg(_) => None,
            }));
        let ctor = GenericArgsCtor {
            args,
            constraints,
            parenthesized: hir::GenericArgsParentheses::No,
            span: data.span,
        };
        (ctor, !has_non_lt_args && param_mode == ParamMode::Optional)
    }

    fn lower_parenthesized_parameter_data(
        &mut self,
        data: &ParenthesizedArgs,
        itctx: ImplTraitContext,
        bound_modifier_allowed_features: Option<Arc<[Symbol]>>,
    ) -> (GenericArgsCtor<'hir>, bool) {
        // Switch to `PassThrough` mode for anonymous lifetimes; this
        // means that we permit things like `&Ref<T>`, where `Ref` has
        // a hidden lifetime parameter. This is needed for backwards
        // compatibility, even in contexts like an impl header where
        // we generally don't permit such things (see #51008).
        let ParenthesizedArgs { span, inputs, inputs_span, output } = data;
        let inputs = self.arena.alloc_from_iter(inputs.iter().map(|ty| {
            self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
        }));
        let output_ty = match output {
            // Only allow `impl Trait` in return position. i.e.:
            // ```rust
            // fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug
            // //      disallowed --^^^^^^^^^^        allowed --^^^^^^^^^^
            // ```
            FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::OpaqueTy { .. }) => {
                if self.tcx.features().impl_trait_in_fn_trait_return() {
                    self.lower_ty_alloc(ty, itctx)
                } else {
                    self.lower_ty_alloc(
                        ty,
                        ImplTraitContext::FeatureGated(
                            ImplTraitPosition::FnTraitReturn,
                            sym::impl_trait_in_fn_trait_return,
                        ),
                    )
                }
            }
            FnRetTy::Ty(ty) => self
                .lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)),
            FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])),
        };
        let args = smallvec![GenericArg::Type(
            self.arena.alloc(self.ty_tup(*inputs_span, inputs)).try_as_ambig_ty().unwrap()
        )];

        // If we have a bound like `async Fn() -> T`, make sure that we mark the
        // `Output = T` associated type bound with the right feature gates.
        let mut output_span = output_ty.span;
        if let Some(bound_modifier_allowed_features) = bound_modifier_allowed_features {
            output_span = self.mark_span_with_reason(
                DesugaringKind::BoundModifier,
                output_span,
                Some(bound_modifier_allowed_features),
            );
        }
        let constraint = self.assoc_ty_binding(sym::Output, output_span, output_ty);

        (
            GenericArgsCtor {
                args,
                constraints: arena_vec![self; constraint],
                parenthesized: hir::GenericArgsParentheses::ParenSugar,
                span: data.inputs_span,
            },
            false,
        )
    }

    /// An associated type binding (i.e., associated type equality constraint).
    pub(crate) fn assoc_ty_binding(
        &mut self,
        assoc_ty_name: rustc_span::Symbol,
        span: Span,
        ty: &'hir hir::Ty<'hir>,
    ) -> hir::AssocItemConstraint<'hir> {
        let ident = Ident::with_dummy_span(assoc_ty_name);
        let kind = hir::AssocItemConstraintKind::Equality { term: ty.into() };
        let args = arena_vec![self;];
        let constraints = arena_vec![self;];
        let gen_args = self.arena.alloc(hir::GenericArgs {
            args,
            constraints,
            parenthesized: hir::GenericArgsParentheses::No,
            span_ext: DUMMY_SP,
        });
        hir::AssocItemConstraint {
            hir_id: self.next_id(),
            gen_args,
            span: self.lower_span(span),
            ident,
            kind,
        }
    }

    /// When a bound is annotated with `async`, it signals to lowering that the trait
    /// that the bound refers to should be mapped to the "async" flavor of the trait.
    ///
    /// This only needs to be done until we unify `AsyncFn` and `Fn` traits into one
    /// that is generic over `async`ness, if that's ever possible, or modify the
    /// lowering of `async Fn()` bounds to desugar to another trait like `LendingFn`.
    fn map_trait_to_async_trait(&self, def_id: DefId) -> Option<DefId> {
        let lang_items = self.tcx.lang_items();
        match self.tcx.fn_trait_kind_from_def_id(def_id)? {
            ty::ClosureKind::Fn => lang_items.async_fn_trait(),
            ty::ClosureKind::FnMut => lang_items.async_fn_mut_trait(),
            ty::ClosureKind::FnOnce => lang_items.async_fn_once_trait(),
        }
    }
}
