use std::sync::{Arc, LazyLock};
use std::{io, mem};

use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::unord::UnordSet;
use rustc_driver::USING_INTERNAL_FEATURES;
use rustc_errors::TerminalUrl;
use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter;
use rustc_errors::codes::*;
use rustc_errors::emitter::{DynEmitter, HumanReadableErrorType, OutputTheme, stderr_destination};
use rustc_errors::json::JsonEmitter;
use rustc_feature::UnstableFeatures;
use rustc_hir::def::Res;
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{HirId, Path};
use rustc_lint::{MissingDoc, late_lint_mod};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
use rustc_session::config::{
    self, CrateType, ErrorOutputType, Input, OutputType, OutputTypes, ResolveDocLinks,
};
pub(crate) use rustc_session::config::{Options, UnstableOptions};
use rustc_session::{Session, lint};
use rustc_span::source_map;
use rustc_span::symbol::sym;
use tracing::{debug, info};

use crate::clean::inline::build_trait;
use crate::clean::{self, ItemId};
use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
use crate::formats::cache::Cache;
use crate::html::macro_expansion::{ExpandedCode, source_macro_expansion};
use crate::passes;
use crate::passes::Condition::*;
use crate::passes::collect_intra_doc_links::LinkCollector;

pub(crate) struct DocContext<'tcx> {
    pub(crate) tcx: TyCtxt<'tcx>,
    /// Used for normalization.
    ///
    /// Most of this logic is copied from rustc_lint::late.
    pub(crate) param_env: ParamEnv<'tcx>,
    /// Later on moved through `clean::Crate` into `cache`
    pub(crate) external_traits: FxIndexMap<DefId, clean::Trait>,
    /// Used while populating `external_traits` to ensure we don't process the same trait twice at
    /// the same time.
    pub(crate) active_extern_traits: DefIdSet,
    /// The current set of parameter instantiations for expanding type aliases at the HIR level.
    ///
    /// Maps from the `DefId` of a lifetime or type parameter to the
    /// generic argument it's currently instantiated to in this context.
    // FIXME(#82852): We don't record const params since we don't visit const exprs at all and
    // therefore wouldn't use the corresp. generic arg anyway. Add support for them.
    pub(crate) args: DefIdMap<clean::GenericArg>,
    pub(crate) current_type_aliases: DefIdMap<usize>,
    /// Table synthetic type parameter for `impl Trait` in argument position -> bounds
    pub(crate) impl_trait_bounds: FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>,
    /// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`.
    // FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set.
    pub(crate) generated_synthetics: FxHashSet<(Ty<'tcx>, DefId)>,
    pub(crate) auto_traits: Vec<DefId>,
    /// This same cache is used throughout rustdoc, including in [`crate::html::render`].
    pub(crate) cache: Cache,
    /// Used by [`clean::inline`] to tell if an item has already been inlined.
    pub(crate) inlined: FxHashSet<ItemId>,
    /// Used by `calculate_doc_coverage`.
    pub(crate) output_format: OutputFormat,
    /// Used by `strip_private`.
    pub(crate) show_coverage: bool,
}

impl<'tcx> DocContext<'tcx> {
    pub(crate) fn sess(&self) -> &'tcx Session {
        self.tcx.sess
    }

    pub(crate) fn with_param_env<T, F: FnOnce(&mut Self) -> T>(
        &mut self,
        def_id: DefId,
        f: F,
    ) -> T {
        let old_param_env = mem::replace(&mut self.param_env, self.tcx.param_env(def_id));
        let ret = f(self);
        self.param_env = old_param_env;
        ret
    }

    pub(crate) fn typing_env(&self) -> ty::TypingEnv<'tcx> {
        ty::TypingEnv {
            typing_mode: ty::TypingMode::non_body_analysis(),
            param_env: self.param_env,
        }
    }

    /// Call the closure with the given parameters set as
    /// the generic parameters for a type alias' RHS.
    pub(crate) fn enter_alias<F, R>(
        &mut self,
        args: DefIdMap<clean::GenericArg>,
        def_id: DefId,
        f: F,
    ) -> R
    where
        F: FnOnce(&mut Self) -> R,
    {
        let old_args = mem::replace(&mut self.args, args);
        *self.current_type_aliases.entry(def_id).or_insert(0) += 1;
        let r = f(self);
        self.args = old_args;
        if let Some(count) = self.current_type_aliases.get_mut(&def_id) {
            *count -= 1;
            if *count == 0 {
                self.current_type_aliases.remove(&def_id);
            }
        }
        r
    }

    /// Like `tcx.local_def_id_to_hir_id()`, but skips calling it on fake DefIds.
    /// (This avoids a slice-index-out-of-bounds panic.)
    pub(crate) fn as_local_hir_id(tcx: TyCtxt<'_>, item_id: ItemId) -> Option<HirId> {
        match item_id {
            ItemId::DefId(real_id) => {
                real_id.as_local().map(|def_id| tcx.local_def_id_to_hir_id(def_id))
            }
            // FIXME: Can this be `Some` for `Auto` or `Blanket`?
            _ => None,
        }
    }

    /// Returns `true` if the JSON output format is enabled for generating the crate content.
    ///
    /// If another option like `--show-coverage` is enabled, it will return `false`.
    pub(crate) fn is_json_output(&self) -> bool {
        self.output_format.is_json() && !self.show_coverage
    }

    /// If `--document-private-items` was passed to rustdoc.
    pub(crate) fn document_private(&self) -> bool {
        self.cache.document_private
    }

    /// If `--document-hidden-items` was passed to rustdoc.
    pub(crate) fn document_hidden(&self) -> bool {
        self.cache.document_hidden
    }
}

/// Creates a new `DiagCtxt` that can be used to emit warnings and errors.
///
/// If the given `error_format` is `ErrorOutputType::Json` and no `SourceMap` is given, a new one
/// will be created for the `DiagCtxt`.
pub(crate) fn new_dcx(
    error_format: ErrorOutputType,
    source_map: Option<Arc<source_map::SourceMap>>,
    diagnostic_width: Option<usize>,
    unstable_opts: &UnstableOptions,
) -> rustc_errors::DiagCtxt {
    let translator = rustc_driver::default_translator();
    let emitter: Box<DynEmitter> = match error_format {
        ErrorOutputType::HumanReadable { kind, color_config } => match kind {
            HumanReadableErrorType { short, unicode } => Box::new(
                AnnotateSnippetEmitter::new(stderr_destination(color_config), translator)
                    .sm(source_map.map(|sm| sm as _))
                    .short_message(short)
                    .diagnostic_width(diagnostic_width)
                    .track_diagnostics(unstable_opts.track_diagnostics)
                    .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii })
                    .ui_testing(unstable_opts.ui_testing),
            ),
        },
        ErrorOutputType::Json { pretty, json_rendered, color_config } => {
            let source_map = source_map.unwrap_or_else(|| {
                Arc::new(source_map::SourceMap::new(source_map::FilePathMapping::empty()))
            });
            Box::new(
                JsonEmitter::new(
                    Box::new(io::BufWriter::new(io::stderr())),
                    Some(source_map),
                    translator,
                    pretty,
                    json_rendered,
                    color_config,
                )
                .ui_testing(unstable_opts.ui_testing)
                .diagnostic_width(diagnostic_width)
                .track_diagnostics(unstable_opts.track_diagnostics)
                .terminal_url(TerminalUrl::No),
            )
        }
    };

    rustc_errors::DiagCtxt::new(emitter).with_flags(unstable_opts.dcx_flags(true))
}

/// Parse, resolve, and typecheck the given crate.
pub(crate) fn create_config(
    input: Input,
    RustdocOptions {
        crate_name,
        proc_macro_crate,
        error_format,
        diagnostic_width,
        libs,
        externs,
        mut cfgs,
        check_cfgs,
        codegen_options,
        unstable_opts,
        target,
        edition,
        sysroot,
        lint_opts,
        describe_lints,
        lint_cap,
        scrape_examples_options,
        remap_path_prefix,
        target_modifiers,
        ..
    }: RustdocOptions,
    render_options: &RenderOptions,
) -> rustc_interface::Config {
    // Add the doc cfg into the doc build.
    cfgs.push("doc".to_string());

    // By default, rustdoc ignores all lints.
    // Specifically unblock lints relevant to documentation or the lint machinery itself.
    let mut lints_to_show = vec![
        // it's unclear whether these should be part of rustdoc directly (#77364)
        rustc_lint::builtin::MISSING_DOCS.name.to_string(),
        rustc_lint::builtin::INVALID_DOC_ATTRIBUTES.name.to_string(),
        // these are definitely not part of rustdoc, but we want to warn on them anyway.
        rustc_lint::builtin::RENAMED_AND_REMOVED_LINTS.name.to_string(),
        rustc_lint::builtin::UNKNOWN_LINTS.name.to_string(),
        rustc_lint::builtin::UNEXPECTED_CFGS.name.to_string(),
        // this lint is needed to support `#[expect]` attributes
        rustc_lint::builtin::UNFULFILLED_LINT_EXPECTATIONS.name.to_string(),
    ];
    lints_to_show.extend(crate::lint::RUSTDOC_LINTS.iter().map(|lint| lint.name.to_string()));

    let (lint_opts, lint_caps) = crate::lint::init_lints(lints_to_show, lint_opts, |lint| {
        Some((lint.name_lower(), lint::Allow))
    });

    let crate_types =
        if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
    let resolve_doc_links = if render_options.document_private {
        ResolveDocLinks::All
    } else {
        ResolveDocLinks::Exported
    };
    let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false);
    // plays with error output here!
    let sessopts = config::Options {
        sysroot,
        search_paths: libs,
        crate_types,
        lint_opts,
        lint_cap,
        cg: codegen_options,
        externs,
        target_triple: target,
        unstable_features: UnstableFeatures::from_environment(crate_name.as_deref()),
        actually_rustdoc: true,
        resolve_doc_links,
        unstable_opts,
        error_format,
        diagnostic_width,
        edition,
        describe_lints,
        crate_name,
        test,
        remap_path_prefix,
        output_types: if let Some(file) = render_options.dep_info() {
            OutputTypes::new(&[(OutputType::DepInfo, file.cloned())])
        } else {
            OutputTypes::new(&[])
        },
        target_modifiers,
        ..Options::default()
    };

    rustc_interface::Config {
        opts: sessopts,
        crate_cfg: cfgs,
        crate_check_cfg: check_cfgs,
        input,
        output_file: None,
        output_dir: None,
        file_loader: None,
        locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
        lint_caps,
        psess_created: None,
        hash_untracked_state: None,
        register_lints: Some(Box::new(crate::lint::register_lints)),
        override_queries: Some(|_sess, providers| {
            // We do not register late module lints, so this only runs `MissingDoc`.
            // Most lints will require typechecking, so just don't run them.
            providers.lint_mod = |tcx, module_def_id| late_lint_mod(tcx, module_def_id, MissingDoc);
            // hack so that `used_trait_imports` won't try to call typeck
            providers.used_trait_imports = |_, _| {
                static EMPTY_SET: LazyLock<UnordSet<LocalDefId>> = LazyLock::new(UnordSet::default);
                &EMPTY_SET
            };
            // In case typeck does end up being called, don't ICE in case there were name resolution errors
            providers.typeck = move |tcx, def_id| {
                // Closures' tables come from their outermost function,
                // as they are part of the same "inference environment".
                // This avoids emitting errors for the parent twice (see similar code in `typeck_with_fallback`)
                let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id()).expect_local();
                if typeck_root_def_id != def_id {
                    return tcx.typeck(typeck_root_def_id);
                }

                let body = tcx.hir_body_owned_by(def_id);
                debug!("visiting body for {def_id:?}");
                EmitIgnoredResolutionErrors::new(tcx).visit_body(body);
                (rustc_interface::DEFAULT_QUERY_PROVIDERS.typeck)(tcx, def_id)
            };
        }),
        extra_symbols: Vec::new(),
        make_codegen_backend: None,
        registry: rustc_driver::diagnostics_registry(),
        ice_file: None,
        using_internal_features: &USING_INTERNAL_FEATURES,
    }
}

pub(crate) fn run_global_ctxt(
    tcx: TyCtxt<'_>,
    show_coverage: bool,
    render_options: RenderOptions,
    output_format: OutputFormat,
) -> (clean::Crate, RenderOptions, Cache, FxHashMap<rustc_span::BytePos, Vec<ExpandedCode>>) {
    // Certain queries assume that some checks were run elsewhere
    // (see https://github.com/rust-lang/rust/pull/73566#issuecomment-656954425),
    // so type-check everything other than function bodies in this crate before running lints.

    let expanded_macros = {
        // We need for these variables to be removed to ensure that the `Crate` won't be "stolen"
        // anymore.
        let (_resolver, krate) = &*tcx.resolver_for_lowering().borrow();

        source_macro_expansion(&krate, &render_options, output_format, tcx.sess.source_map())
    };

    // NOTE: this does not call `tcx.analysis()` so that we won't
    // typeck function bodies or run the default rustc lints.
    // (see `override_queries` in the `config`)

    // NOTE: These are copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
    let _ = tcx.sess.time("wf_checking", || tcx.ensure_ok().check_type_wf(()));

    tcx.dcx().abort_if_errors();

    tcx.sess.time("missing_docs", || rustc_lint::check_crate(tcx));
    tcx.sess.time("check_mod_attrs", || {
        tcx.hir_for_each_module(|module| tcx.ensure_ok().check_mod_attrs(module))
    });
    rustc_passes::stability::check_unused_or_stable_features(tcx);

    let auto_traits =
        tcx.visible_traits().filter(|&trait_def_id| tcx.trait_is_auto(trait_def_id)).collect();

    let mut ctxt = DocContext {
        tcx,
        param_env: ParamEnv::empty(),
        external_traits: Default::default(),
        active_extern_traits: Default::default(),
        args: Default::default(),
        current_type_aliases: Default::default(),
        impl_trait_bounds: Default::default(),
        generated_synthetics: Default::default(),
        auto_traits,
        cache: Cache::new(render_options.document_private, render_options.document_hidden),
        inlined: FxHashSet::default(),
        output_format,
        show_coverage,
    };

    for cnum in tcx.crates(()) {
        crate::visit_lib::lib_embargo_visit_item(&mut ctxt, cnum.as_def_id());
    }

    // Small hack to force the Sized trait to be present.
    //
    // Note that in case of `#![no_core]`, the trait is not available.
    if let Some(sized_trait_did) = ctxt.tcx.lang_items().sized_trait() {
        let sized_trait = build_trait(&mut ctxt, sized_trait_did);
        ctxt.external_traits.insert(sized_trait_did, sized_trait);
    }

    let mut krate = tcx.sess.time("clean_crate", || clean::krate(&mut ctxt));

    if krate.module.doc_value().is_empty() {
        let help = format!(
            "The following guide may be of use:\n\
            {}/rustdoc/how-to-write-documentation.html",
            crate::DOC_RUST_LANG_ORG_VERSION
        );
        tcx.node_lint(
            crate::lint::MISSING_CRATE_LEVEL_DOCS,
            DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(),
            |lint| {
                if let Some(local_def_id) = krate.module.item_id.as_local_def_id() {
                    lint.span(tcx.def_span(local_def_id));
                }
                lint.primary_message("no documentation found for this crate's top-level module");
                lint.help(help);
            },
        );
    }

    info!("Executing passes");

    let mut visited = FxHashMap::default();
    let mut ambiguous = FxIndexMap::default();

    for p in passes::defaults(show_coverage) {
        let run = match p.condition {
            Always => true,
            WhenDocumentPrivate => ctxt.document_private(),
            WhenNotDocumentPrivate => !ctxt.document_private(),
            WhenNotDocumentHidden => !ctxt.document_hidden(),
        };
        if run {
            debug!("running pass {}", p.pass.name);
            if let Some(run_fn) = p.pass.run {
                krate = tcx.sess.time(p.pass.name, || run_fn(krate, &mut ctxt));
            } else {
                let (k, LinkCollector { visited_links, ambiguous_links, .. }) =
                    passes::collect_intra_doc_links::collect_intra_doc_links(krate, &mut ctxt);
                krate = k;
                visited = visited_links;
                ambiguous = ambiguous_links;
            }
        }
    }

    tcx.sess.time("check_lint_expectations", || tcx.check_expectations(Some(sym::rustdoc)));

    krate =
        tcx.sess.time("create_format_cache", || Cache::populate(&mut ctxt, krate, &render_options));

    let mut collector =
        LinkCollector { cx: &mut ctxt, visited_links: visited, ambiguous_links: ambiguous };
    collector.resolve_ambiguities();

    tcx.dcx().abort_if_errors();

    (krate, render_options, ctxt.cache, expanded_macros)
}

/// Due to <https://github.com/rust-lang/rust/pull/73566>,
/// the name resolution pass may find errors that are never emitted.
/// If typeck is called after this happens, then we'll get an ICE:
/// 'Res::Error found but not reported'. To avoid this, emit the errors now.
struct EmitIgnoredResolutionErrors<'tcx> {
    tcx: TyCtxt<'tcx>,
}

impl<'tcx> EmitIgnoredResolutionErrors<'tcx> {
    fn new(tcx: TyCtxt<'tcx>) -> Self {
        Self { tcx }
    }
}

impl<'tcx> Visitor<'tcx> for EmitIgnoredResolutionErrors<'tcx> {
    type NestedFilter = nested_filter::OnlyBodies;

    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
        // We need to recurse into nested closures,
        // since those will fallback to the parent for type checking.
        self.tcx
    }

    fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
        debug!("visiting path {path:?}");
        if path.res == Res::Err {
            // We have less context here than in rustc_resolve,
            // so we can only emit the name and span.
            // However we can give a hint that rustc_resolve will have more info.
            let label = format!(
                "could not resolve path `{}`",
                path.segments
                    .iter()
                    .map(|segment| segment.ident.as_str())
                    .intersperse("::")
                    .collect::<String>()
            );
            rustc_errors::struct_span_code_err!(
                self.tcx.dcx(),
                path.span,
                E0433,
                "failed to resolve: {label}",
            )
            .with_span_label(path.span, label)
            .with_note("this error was originally ignored because you are running `rustdoc`")
            .with_note("try running again with `rustc` or `cargo check` and you may get a more detailed error")
            .emit();
        }
        // We could have an outer resolution that succeeded,
        // but with generic parameters that failed.
        // Recurse into the segments so we catch those too.
        intravisit::walk_path(self, path);
    }
}

/// `DefId` or parameter index (`ty::ParamTy.index`) of a synthetic type parameter
/// for `impl Trait` in argument position.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) enum ImplTraitParam {
    DefId(DefId),
    ParamIndex(u32),
}

impl From<DefId> for ImplTraitParam {
    fn from(did: DefId) -> Self {
        ImplTraitParam::DefId(did)
    }
}

impl From<u32> for ImplTraitParam {
    fn from(idx: u32) -> Self {
        ImplTraitParam::ParamIndex(idx)
    }
}
