mod make;
mod markdown;
mod runner;
mod rust;

use std::fs::File;
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::process::{self, Command, Stdio};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};
use std::{panic, str};

pub(crate) use make::DocTestBuilder;
pub(crate) use markdown::test as test_markdown;
use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
use rustc_errors::{ColorConfig, DiagCtxtHandle, ErrorGuaranteed, FatalError};
use rustc_hir::CRATE_HIR_ID;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_interface::interface;
use rustc_session::config::{self, CrateType, ErrorOutputType, Input};
use rustc_session::lint;
use rustc_span::FileName;
use rustc_span::edition::Edition;
use rustc_span::symbol::sym;
use rustc_target::spec::{Target, TargetTriple};
use tempfile::{Builder as TempFileBuilder, TempDir};
use tracing::debug;

use self::rust::HirCollector;
use crate::config::Options as RustdocOptions;
use crate::html::markdown::{ErrorCodes, Ignore, LangString, MdRelLine};
use crate::lint::init_lints;

/// Options that apply to all doctests in a crate or Markdown file (for `rustdoc foo.md`).
#[derive(Clone)]
pub(crate) struct GlobalTestOptions {
    /// Name of the crate (for regular `rustdoc`) or Markdown file (for `rustdoc foo.md`).
    pub(crate) crate_name: String,
    /// Whether to disable the default `extern crate my_crate;` when creating doctests.
    pub(crate) no_crate_inject: bool,
    /// Whether inserting extra indent spaces in code block,
    /// default is `false`, only `true` for generating code link of Rust playground
    pub(crate) insert_indent_space: bool,
    /// Additional crate-level attributes to add to doctests.
    pub(crate) attrs: Vec<String>,
    /// Path to file containing arguments for the invocation of rustc.
    pub(crate) args_file: PathBuf,
}

pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> Result<(), String> {
    let mut file = File::create(file_path)
        .map_err(|error| format!("failed to create args file: {error:?}"))?;

    // We now put the common arguments into the file we created.
    let mut content = vec!["--crate-type=bin".to_string()];

    for cfg in &options.cfgs {
        content.push(format!("--cfg={cfg}"));
    }
    for check_cfg in &options.check_cfgs {
        content.push(format!("--check-cfg={check_cfg}"));
    }

    for lib_str in &options.lib_strs {
        content.push(format!("-L{lib_str}"));
    }
    for extern_str in &options.extern_strs {
        content.push(format!("--extern={extern_str}"));
    }
    content.push("-Ccodegen-units=1".to_string());
    for codegen_options_str in &options.codegen_options_strs {
        content.push(format!("-C{codegen_options_str}"));
    }
    for unstable_option_str in &options.unstable_opts_strs {
        content.push(format!("-Z{unstable_option_str}"));
    }

    let content = content.join("\n");

    file.write_all(content.as_bytes())
        .map_err(|error| format!("failed to write arguments to temporary file: {error:?}"))?;
    Ok(())
}

fn get_doctest_dir() -> io::Result<TempDir> {
    TempFileBuilder::new().prefix("rustdoctest").tempdir()
}

pub(crate) fn run(
    dcx: DiagCtxtHandle<'_>,
    input: Input,
    options: RustdocOptions,
) -> Result<(), ErrorGuaranteed> {
    let invalid_codeblock_attributes_name = crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name;

    // See core::create_config for what's going on here.
    let allowed_lints = vec![
        invalid_codeblock_attributes_name.to_owned(),
        lint::builtin::UNKNOWN_LINTS.name.to_owned(),
        lint::builtin::RENAMED_AND_REMOVED_LINTS.name.to_owned(),
    ];

    let (lint_opts, lint_caps) = init_lints(allowed_lints, options.lint_opts.clone(), |lint| {
        if lint.name == invalid_codeblock_attributes_name {
            None
        } else {
            Some((lint.name_lower(), lint::Allow))
        }
    });

    debug!(?lint_opts);

    let crate_types =
        if options.proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };

    let sessopts = config::Options {
        maybe_sysroot: options.maybe_sysroot.clone(),
        search_paths: options.libs.clone(),
        crate_types,
        lint_opts,
        lint_cap: Some(options.lint_cap.unwrap_or(lint::Forbid)),
        cg: options.codegen_options.clone(),
        externs: options.externs.clone(),
        unstable_features: options.unstable_features,
        actually_rustdoc: true,
        edition: options.edition,
        target_triple: options.target.clone(),
        crate_name: options.crate_name.clone(),
        remap_path_prefix: options.remap_path_prefix.clone(),
        ..config::Options::default()
    };

    let mut cfgs = options.cfgs.clone();
    cfgs.push("doc".to_owned());
    cfgs.push("doctest".to_owned());
    let config = interface::Config {
        opts: sessopts,
        crate_cfg: cfgs,
        crate_check_cfg: options.check_cfgs.clone(),
        input: input.clone(),
        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: None,
        make_codegen_backend: None,
        registry: rustc_driver::diagnostics_registry(),
        ice_file: None,
        using_internal_features: Arc::default(),
        expanded_args: options.expanded_args.clone(),
    };

    let externs = options.externs.clone();
    let json_unused_externs = options.json_unused_externs;

    let temp_dir = match get_doctest_dir()
        .map_err(|error| format!("failed to create temporary directory: {error:?}"))
    {
        Ok(temp_dir) => temp_dir,
        Err(error) => return crate::wrap_return(dcx, Err(error)),
    };
    let args_path = temp_dir.path().join("rustdoc-cfgs");
    crate::wrap_return(dcx, generate_args_file(&args_path, &options))?;

    let CreateRunnableDocTests {
        standalone_tests,
        mergeable_tests,
        rustdoc_options,
        opts,
        unused_extern_reports,
        compiling_test_count,
        ..
    } = interface::run_compiler(config, |compiler| {
        compiler.enter(|queries| {
            let collector = queries.global_ctxt()?.enter(|tcx| {
                let crate_name = tcx.crate_name(LOCAL_CRATE).to_string();
                let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID);
                let opts = scrape_test_config(crate_name, crate_attrs, args_path);
                let enable_per_target_ignores = options.enable_per_target_ignores;

                let mut collector = CreateRunnableDocTests::new(options, opts);
                let hir_collector = HirCollector::new(
                    ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()),
                    enable_per_target_ignores,
                    tcx,
                );
                let tests = hir_collector.collect_crate();
                tests.into_iter().for_each(|t| collector.add_test(t));

                collector
            });
            if compiler.sess.dcx().has_errors().is_some() {
                FatalError.raise();
            }

            Ok(collector)
        })
    })?;

    run_tests(opts, &rustdoc_options, &unused_extern_reports, standalone_tests, mergeable_tests);

    let compiling_test_count = compiling_test_count.load(Ordering::SeqCst);

    // Collect and warn about unused externs, but only if we've gotten
    // reports for each doctest
    if json_unused_externs.is_enabled() {
        let unused_extern_reports: Vec<_> =
            std::mem::take(&mut unused_extern_reports.lock().unwrap());
        if unused_extern_reports.len() == compiling_test_count {
            let extern_names =
                externs.iter().map(|(name, _)| name).collect::<FxIndexSet<&String>>();
            let mut unused_extern_names = unused_extern_reports
                .iter()
                .map(|uexts| uexts.unused_extern_names.iter().collect::<FxIndexSet<&String>>())
                .fold(extern_names, |uextsa, uextsb| {
                    uextsa.intersection(&uextsb).copied().collect::<FxIndexSet<&String>>()
                })
                .iter()
                .map(|v| (*v).clone())
                .collect::<Vec<String>>();
            unused_extern_names.sort();
            // Take the most severe lint level
            let lint_level = unused_extern_reports
                .iter()
                .map(|uexts| uexts.lint_level.as_str())
                .max_by_key(|v| match *v {
                    "warn" => 1,
                    "deny" => 2,
                    "forbid" => 3,
                    // The allow lint level is not expected,
                    // as if allow is specified, no message
                    // is to be emitted.
                    v => unreachable!("Invalid lint level '{v}'"),
                })
                .unwrap_or("warn")
                .to_string();
            let uext = UnusedExterns { lint_level, unused_extern_names };
            let unused_extern_json = serde_json::to_string(&uext).unwrap();
            eprintln!("{unused_extern_json}");
        }
    }

    Ok(())
}

pub(crate) fn run_tests(
    opts: GlobalTestOptions,
    rustdoc_options: &Arc<RustdocOptions>,
    unused_extern_reports: &Arc<Mutex<Vec<UnusedExterns>>>,
    mut standalone_tests: Vec<test::TestDescAndFn>,
    mergeable_tests: FxIndexMap<Edition, Vec<(DocTestBuilder, ScrapedDocTest)>>,
) {
    let mut test_args = Vec::with_capacity(rustdoc_options.test_args.len() + 1);
    test_args.insert(0, "rustdoctest".to_string());
    test_args.extend_from_slice(&rustdoc_options.test_args);
    if rustdoc_options.nocapture {
        test_args.push("--nocapture".to_string());
    }

    let mut nb_errors = 0;
    let mut ran_edition_tests = 0;
    let target_str = rustdoc_options.target.to_string();

    for (edition, mut doctests) in mergeable_tests {
        if doctests.is_empty() {
            continue;
        }
        doctests.sort_by(|(_, a), (_, b)| a.name.cmp(&b.name));

        let mut tests_runner = runner::DocTestRunner::new();

        let rustdoc_test_options = IndividualTestOptions::new(
            rustdoc_options,
            &Some(format!("merged_doctest_{edition}")),
            PathBuf::from(format!("doctest_{edition}.rs")),
        );

        for (doctest, scraped_test) in &doctests {
            tests_runner.add_test(doctest, scraped_test, &target_str);
        }
        if let Ok(success) = tests_runner.run_merged_tests(
            rustdoc_test_options,
            edition,
            &opts,
            &test_args,
            rustdoc_options,
        ) {
            ran_edition_tests += 1;
            if !success {
                nb_errors += 1;
            }
            continue;
        }
        // We failed to compile all compatible tests as one so we push them into the
        // `standalone_tests` doctests.
        debug!("Failed to compile compatible doctests for edition {} all at once", edition);
        for (doctest, scraped_test) in doctests {
            doctest.generate_unique_doctest(
                &scraped_test.text,
                scraped_test.langstr.test_harness,
                &opts,
                Some(&opts.crate_name),
            );
            standalone_tests.push(generate_test_desc_and_fn(
                doctest,
                scraped_test,
                opts.clone(),
                Arc::clone(rustdoc_options),
                unused_extern_reports.clone(),
            ));
        }
    }

    // We need to call `test_main` even if there is no doctest to run to get the output
    // `running 0 tests...`.
    if ran_edition_tests == 0 || !standalone_tests.is_empty() {
        standalone_tests.sort_by(|a, b| a.desc.name.as_slice().cmp(b.desc.name.as_slice()));
        test::test_main(&test_args, standalone_tests, None);
    }
    if nb_errors != 0 {
        // libtest::ERROR_EXIT_CODE is not public but it's the same value.
        std::process::exit(101);
    }
}

// Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade.
fn scrape_test_config(
    crate_name: String,
    attrs: &[ast::Attribute],
    args_file: PathBuf,
) -> GlobalTestOptions {
    use rustc_ast_pretty::pprust;

    let mut opts = GlobalTestOptions {
        crate_name,
        no_crate_inject: false,
        attrs: Vec::new(),
        insert_indent_space: false,
        args_file,
    };

    let test_attrs: Vec<_> = attrs
        .iter()
        .filter(|a| a.has_name(sym::doc))
        .flat_map(|a| a.meta_item_list().unwrap_or_default())
        .filter(|a| a.has_name(sym::test))
        .collect();
    let attrs = test_attrs.iter().flat_map(|a| a.meta_item_list().unwrap_or(&[]));

    for attr in attrs {
        if attr.has_name(sym::no_crate_inject) {
            opts.no_crate_inject = true;
        }
        if attr.has_name(sym::attr)
            && let Some(l) = attr.meta_item_list()
        {
            for item in l {
                opts.attrs.push(pprust::meta_list_item_to_string(item));
            }
        }
    }

    opts
}

/// Documentation test failure modes.
enum TestFailure {
    /// The test failed to compile.
    CompileError,
    /// The test is marked `compile_fail` but compiled successfully.
    UnexpectedCompilePass,
    /// The test failed to compile (as expected) but the compiler output did not contain all
    /// expected error codes.
    MissingErrorCodes(Vec<String>),
    /// The test binary was unable to be executed.
    ExecutionError(io::Error),
    /// The test binary exited with a non-zero exit code.
    ///
    /// This typically means an assertion in the test failed or another form of panic occurred.
    ExecutionFailure(process::Output),
    /// The test is marked `should_panic` but the test binary executed successfully.
    UnexpectedRunPass,
}

enum DirState {
    Temp(tempfile::TempDir),
    Perm(PathBuf),
}

impl DirState {
    fn path(&self) -> &std::path::Path {
        match self {
            DirState::Temp(t) => t.path(),
            DirState::Perm(p) => p.as_path(),
        }
    }
}

// NOTE: Keep this in sync with the equivalent structs in rustc
// and cargo.
// We could unify this struct the one in rustc but they have different
// ownership semantics, so doing so would create wasteful allocations.
#[derive(serde::Serialize, serde::Deserialize)]
pub(crate) struct UnusedExterns {
    /// Lint level of the unused_crate_dependencies lint
    lint_level: String,
    /// List of unused externs by their names.
    unused_extern_names: Vec<String>,
}

fn add_exe_suffix(input: String, target: &TargetTriple) -> String {
    let exe_suffix = match target {
        TargetTriple::TargetTriple(_) => Target::expect_builtin(target).options.exe_suffix,
        TargetTriple::TargetJson { contents, .. } => {
            Target::from_json(contents.parse().unwrap()).unwrap().0.options.exe_suffix
        }
    };
    input + &exe_suffix
}

fn wrapped_rustc_command(rustc_wrappers: &[PathBuf], rustc_binary: &Path) -> Command {
    let mut args = rustc_wrappers.iter().map(PathBuf::as_path).chain([rustc_binary]);

    let exe = args.next().expect("unable to create rustc command");
    let mut command = Command::new(exe);
    for arg in args {
        command.arg(arg);
    }

    command
}

/// Information needed for running a bundle of doctests.
///
/// This data structure contains the "full" test code, including the wrappers
/// (if multiple doctests are merged), `main` function,
/// and everything needed to calculate the compiler's command-line arguments.
/// The `# ` prefix on boring lines has also been stripped.
pub(crate) struct RunnableDocTest {
    full_test_code: String,
    full_test_line_offset: usize,
    test_opts: IndividualTestOptions,
    global_opts: GlobalTestOptions,
    langstr: LangString,
    line: usize,
    edition: Edition,
    no_run: bool,
    is_multiple_tests: bool,
}

impl RunnableDocTest {
    fn path_for_merged_doctest(&self) -> PathBuf {
        self.test_opts.outdir.path().join(format!("doctest_{}.rs", self.edition))
    }
}

/// Execute a `RunnableDoctest`.
///
/// This is the function that calculates the compiler command line, invokes the compiler, then
/// invokes the test or tests in a separate executable (if applicable).
fn run_test(
    doctest: RunnableDocTest,
    rustdoc_options: &RustdocOptions,
    supports_color: bool,
    report_unused_externs: impl Fn(UnusedExterns),
) -> Result<(), TestFailure> {
    let langstr = &doctest.langstr;
    // Make sure we emit well-formed executable names for our target.
    let rust_out = add_exe_suffix("rust_out".to_owned(), &rustdoc_options.target);
    let output_file = doctest.test_opts.outdir.path().join(rust_out);

    let rustc_binary = rustdoc_options
        .test_builder
        .as_deref()
        .unwrap_or_else(|| rustc_interface::util::rustc_path().expect("found rustc"));
    let mut compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);

    compiler.arg(format!("@{}", doctest.global_opts.args_file.display()));

    if let Some(sysroot) = &rustdoc_options.maybe_sysroot {
        compiler.arg(format!("--sysroot={}", sysroot.display()));
    }

    compiler.arg("--edition").arg(doctest.edition.to_string());
    if !doctest.is_multiple_tests {
        // Setting these environment variables is unneeded if this is a merged doctest.
        compiler.env("UNSTABLE_RUSTDOC_TEST_PATH", &doctest.test_opts.path);
        compiler.env(
            "UNSTABLE_RUSTDOC_TEST_LINE",
            format!("{}", doctest.line as isize - doctest.full_test_line_offset as isize),
        );
    }
    compiler.arg("-o").arg(&output_file);
    if langstr.test_harness {
        compiler.arg("--test");
    }
    if rustdoc_options.json_unused_externs.is_enabled() && !langstr.compile_fail {
        compiler.arg("--error-format=json");
        compiler.arg("--json").arg("unused-externs");
        compiler.arg("-W").arg("unused_crate_dependencies");
        compiler.arg("-Z").arg("unstable-options");
    }

    if doctest.no_run && !langstr.compile_fail && rustdoc_options.persist_doctests.is_none() {
        // FIXME: why does this code check if it *shouldn't* persist doctests
        //        -- shouldn't it be the negation?
        compiler.arg("--emit=metadata");
    }
    compiler.arg("--target").arg(match &rustdoc_options.target {
        TargetTriple::TargetTriple(s) => s,
        TargetTriple::TargetJson { path_for_rustdoc, .. } => {
            path_for_rustdoc.to_str().expect("target path must be valid unicode")
        }
    });
    if let ErrorOutputType::HumanReadable(kind, color_config) = rustdoc_options.error_format {
        let short = kind.short();

        if short {
            compiler.arg("--error-format").arg("short");
        }

        match color_config {
            ColorConfig::Never => {
                compiler.arg("--color").arg("never");
            }
            ColorConfig::Always => {
                compiler.arg("--color").arg("always");
            }
            ColorConfig::Auto => {
                compiler.arg("--color").arg(if supports_color { "always" } else { "never" });
            }
        }
    }

    // If this is a merged doctest, we need to write it into a file instead of using stdin
    // because if the size of the merged doctests is too big, it'll simply break stdin.
    if doctest.is_multiple_tests {
        // It makes the compilation failure much faster if it is for a combined doctest.
        compiler.arg("--error-format=short");
        let input_file = doctest.path_for_merged_doctest();
        if std::fs::write(&input_file, &doctest.full_test_code).is_err() {
            // If we cannot write this file for any reason, we leave. All combined tests will be
            // tested as standalone tests.
            return Err(TestFailure::CompileError);
        }
        compiler.arg(input_file);
        if !rustdoc_options.nocapture {
            // If `nocapture` is disabled, then we don't display rustc's output when compiling
            // the merged doctests.
            compiler.stderr(Stdio::null());
        }
    } else {
        compiler.arg("-");
        compiler.stdin(Stdio::piped());
        compiler.stderr(Stdio::piped());
    }

    debug!("compiler invocation for doctest: {compiler:?}");

    let mut child = compiler.spawn().expect("Failed to spawn rustc process");
    let output = if doctest.is_multiple_tests {
        let status = child.wait().expect("Failed to wait");
        process::Output { status, stdout: Vec::new(), stderr: Vec::new() }
    } else {
        let stdin = child.stdin.as_mut().expect("Failed to open stdin");
        stdin.write_all(doctest.full_test_code.as_bytes()).expect("could write out test sources");
        child.wait_with_output().expect("Failed to read stdout")
    };

    struct Bomb<'a>(&'a str);
    impl Drop for Bomb<'_> {
        fn drop(&mut self) {
            eprint!("{}", self.0);
        }
    }
    let mut out = str::from_utf8(&output.stderr)
        .unwrap()
        .lines()
        .filter(|l| {
            if let Ok(uext) = serde_json::from_str::<UnusedExterns>(l) {
                report_unused_externs(uext);
                false
            } else {
                true
            }
        })
        .intersperse_with(|| "\n")
        .collect::<String>();

    // Add a \n to the end to properly terminate the last line,
    // but only if there was output to be printed
    if !out.is_empty() {
        out.push('\n');
    }

    let _bomb = Bomb(&out);
    match (output.status.success(), langstr.compile_fail) {
        (true, true) => {
            return Err(TestFailure::UnexpectedCompilePass);
        }
        (true, false) => {}
        (false, true) => {
            if !langstr.error_codes.is_empty() {
                // We used to check if the output contained "error[{}]: " but since we added the
                // colored output, we can't anymore because of the color escape characters before
                // the ":".
                let missing_codes: Vec<String> = langstr
                    .error_codes
                    .iter()
                    .filter(|err| !out.contains(&format!("error[{err}]")))
                    .cloned()
                    .collect();

                if !missing_codes.is_empty() {
                    return Err(TestFailure::MissingErrorCodes(missing_codes));
                }
            }
        }
        (false, false) => {
            return Err(TestFailure::CompileError);
        }
    }

    if doctest.no_run {
        return Ok(());
    }

    // Run the code!
    let mut cmd;

    let output_file = make_maybe_absolute_path(output_file);
    if let Some(tool) = &rustdoc_options.runtool {
        let tool = make_maybe_absolute_path(tool.into());
        cmd = Command::new(tool);
        cmd.args(&rustdoc_options.runtool_args);
        cmd.arg(&output_file);
    } else {
        cmd = Command::new(&output_file);
        if doctest.is_multiple_tests {
            cmd.arg("*doctest-bin-path");
            cmd.arg(&output_file);
        }
    }
    if let Some(run_directory) = &rustdoc_options.test_run_directory {
        cmd.current_dir(run_directory);
    }

    let result = if doctest.is_multiple_tests || rustdoc_options.nocapture {
        cmd.status().map(|status| process::Output {
            status,
            stdout: Vec::new(),
            stderr: Vec::new(),
        })
    } else {
        cmd.output()
    };
    match result {
        Err(e) => return Err(TestFailure::ExecutionError(e)),
        Ok(out) => {
            if langstr.should_panic && out.status.success() {
                return Err(TestFailure::UnexpectedRunPass);
            } else if !langstr.should_panic && !out.status.success() {
                return Err(TestFailure::ExecutionFailure(out));
            }
        }
    }

    Ok(())
}

/// Converts a path intended to use as a command to absolute if it is
/// relative, and not a single component.
///
/// This is needed to deal with relative paths interacting with
/// `Command::current_dir` in a platform-specific way.
fn make_maybe_absolute_path(path: PathBuf) -> PathBuf {
    if path.components().count() == 1 {
        // Look up process via PATH.
        path
    } else {
        std::env::current_dir().map(|c| c.join(&path)).unwrap_or_else(|_| path)
    }
}
struct IndividualTestOptions {
    outdir: DirState,
    path: PathBuf,
}

impl IndividualTestOptions {
    fn new(options: &RustdocOptions, test_id: &Option<String>, test_path: PathBuf) -> Self {
        let outdir = if let Some(ref path) = options.persist_doctests {
            let mut path = path.clone();
            path.push(&test_id.as_deref().unwrap_or("<doctest>"));

            if let Err(err) = std::fs::create_dir_all(&path) {
                eprintln!("Couldn't create directory for doctest executables: {err}");
                panic::resume_unwind(Box::new(()));
            }

            DirState::Perm(path)
        } else {
            DirState::Temp(get_doctest_dir().expect("rustdoc needs a tempdir"))
        };

        Self { outdir, path: test_path }
    }
}

/// A doctest scraped from the code, ready to be turned into a runnable test.
///
/// The pipeline goes: [`clean`] AST -> `ScrapedDoctest` -> `RunnableDoctest`.
/// [`run_merged_tests`] converts a bunch of scraped doctests to a single runnable doctest,
/// while [`generate_unique_doctest`] does the standalones.
///
/// [`clean`]: crate::clean
/// [`run_merged_tests`]: crate::doctest::runner::DocTestRunner::run_merged_tests
/// [`generate_unique_doctest`]: crate::doctest::make::DocTestBuilder::generate_unique_doctest
pub(crate) struct ScrapedDocTest {
    filename: FileName,
    line: usize,
    langstr: LangString,
    text: String,
    name: String,
}

impl ScrapedDocTest {
    fn new(
        filename: FileName,
        line: usize,
        logical_path: Vec<String>,
        langstr: LangString,
        text: String,
    ) -> Self {
        let mut item_path = logical_path.join("::");
        item_path.retain(|c| c != ' ');
        if !item_path.is_empty() {
            item_path.push(' ');
        }
        let name =
            format!("{} - {item_path}(line {line})", filename.prefer_remapped_unconditionaly());

        Self { filename, line, langstr, text, name }
    }
    fn edition(&self, opts: &RustdocOptions) -> Edition {
        self.langstr.edition.unwrap_or(opts.edition)
    }

    fn no_run(&self, opts: &RustdocOptions) -> bool {
        self.langstr.no_run || opts.no_run
    }
    fn path(&self) -> PathBuf {
        match &self.filename {
            FileName::Real(path) => {
                if let Some(local_path) = path.local_path() {
                    local_path.to_path_buf()
                } else {
                    // Somehow we got the filename from the metadata of another crate, should never happen
                    unreachable!("doctest from a different crate");
                }
            }
            _ => PathBuf::from(r"doctest.rs"),
        }
    }
}

pub(crate) trait DocTestVisitor {
    fn visit_test(&mut self, test: String, config: LangString, rel_line: MdRelLine);
    fn visit_header(&mut self, _name: &str, _level: u32) {}
}

struct CreateRunnableDocTests {
    standalone_tests: Vec<test::TestDescAndFn>,
    mergeable_tests: FxIndexMap<Edition, Vec<(DocTestBuilder, ScrapedDocTest)>>,

    rustdoc_options: Arc<RustdocOptions>,
    opts: GlobalTestOptions,
    visited_tests: FxHashMap<(String, usize), usize>,
    unused_extern_reports: Arc<Mutex<Vec<UnusedExterns>>>,
    compiling_test_count: AtomicUsize,
    can_merge_doctests: bool,
}

impl CreateRunnableDocTests {
    fn new(rustdoc_options: RustdocOptions, opts: GlobalTestOptions) -> CreateRunnableDocTests {
        let can_merge_doctests = rustdoc_options.edition >= Edition::Edition2024;
        CreateRunnableDocTests {
            standalone_tests: Vec::new(),
            mergeable_tests: FxIndexMap::default(),
            rustdoc_options: Arc::new(rustdoc_options),
            opts,
            visited_tests: FxHashMap::default(),
            unused_extern_reports: Default::default(),
            compiling_test_count: AtomicUsize::new(0),
            can_merge_doctests,
        }
    }

    fn add_test(&mut self, scraped_test: ScrapedDocTest) {
        // For example `module/file.rs` would become `module_file_rs`
        let file = scraped_test
            .filename
            .prefer_local()
            .to_string_lossy()
            .chars()
            .map(|c| if c.is_ascii_alphanumeric() { c } else { '_' })
            .collect::<String>();
        let test_id = format!(
            "{file}_{line}_{number}",
            file = file,
            line = scraped_test.line,
            number = {
                // Increases the current test number, if this file already
                // exists or it creates a new entry with a test number of 0.
                self.visited_tests
                    .entry((file.clone(), scraped_test.line))
                    .and_modify(|v| *v += 1)
                    .or_insert(0)
            },
        );

        let edition = scraped_test.edition(&self.rustdoc_options);
        let doctest = DocTestBuilder::new(
            &scraped_test.text,
            Some(&self.opts.crate_name),
            edition,
            self.can_merge_doctests,
            Some(test_id),
            Some(&scraped_test.langstr),
        );
        let is_standalone = !doctest.can_be_merged
            || scraped_test.langstr.compile_fail
            || scraped_test.langstr.test_harness
            || scraped_test.langstr.standalone_crate
            || self.rustdoc_options.nocapture
            || self.rustdoc_options.test_args.iter().any(|arg| arg == "--show-output");
        if is_standalone {
            let test_desc = self.generate_test_desc_and_fn(doctest, scraped_test);
            self.standalone_tests.push(test_desc);
        } else {
            self.mergeable_tests.entry(edition).or_default().push((doctest, scraped_test));
        }
    }

    fn generate_test_desc_and_fn(
        &mut self,
        test: DocTestBuilder,
        scraped_test: ScrapedDocTest,
    ) -> test::TestDescAndFn {
        if !scraped_test.langstr.compile_fail {
            self.compiling_test_count.fetch_add(1, Ordering::SeqCst);
        }

        generate_test_desc_and_fn(
            test,
            scraped_test,
            self.opts.clone(),
            Arc::clone(&self.rustdoc_options),
            self.unused_extern_reports.clone(),
        )
    }
}

fn generate_test_desc_and_fn(
    test: DocTestBuilder,
    scraped_test: ScrapedDocTest,
    opts: GlobalTestOptions,
    rustdoc_options: Arc<RustdocOptions>,
    unused_externs: Arc<Mutex<Vec<UnusedExterns>>>,
) -> test::TestDescAndFn {
    let target_str = rustdoc_options.target.to_string();
    let rustdoc_test_options =
        IndividualTestOptions::new(&rustdoc_options, &test.test_id, scraped_test.path());

    debug!("creating test {}: {}", scraped_test.name, scraped_test.text);
    test::TestDescAndFn {
        desc: test::TestDesc {
            name: test::DynTestName(scraped_test.name.clone()),
            ignore: match scraped_test.langstr.ignore {
                Ignore::All => true,
                Ignore::None => false,
                Ignore::Some(ref ignores) => ignores.iter().any(|s| target_str.contains(s)),
            },
            ignore_message: None,
            source_file: "",
            start_line: 0,
            start_col: 0,
            end_line: 0,
            end_col: 0,
            // compiler failures are test failures
            should_panic: test::ShouldPanic::No,
            compile_fail: scraped_test.langstr.compile_fail,
            no_run: scraped_test.no_run(&rustdoc_options),
            test_type: test::TestType::DocTest,
        },
        testfn: test::DynTestFn(Box::new(move || {
            doctest_run_fn(
                rustdoc_test_options,
                opts,
                test,
                scraped_test,
                rustdoc_options,
                unused_externs,
            )
        })),
    }
}

fn doctest_run_fn(
    test_opts: IndividualTestOptions,
    global_opts: GlobalTestOptions,
    doctest: DocTestBuilder,
    scraped_test: ScrapedDocTest,
    rustdoc_options: Arc<RustdocOptions>,
    unused_externs: Arc<Mutex<Vec<UnusedExterns>>>,
) -> Result<(), String> {
    let report_unused_externs = |uext| {
        unused_externs.lock().unwrap().push(uext);
    };
    let (full_test_code, full_test_line_offset) = doctest.generate_unique_doctest(
        &scraped_test.text,
        scraped_test.langstr.test_harness,
        &global_opts,
        Some(&global_opts.crate_name),
    );
    let runnable_test = RunnableDocTest {
        full_test_code,
        full_test_line_offset,
        test_opts,
        global_opts,
        langstr: scraped_test.langstr.clone(),
        line: scraped_test.line,
        edition: scraped_test.edition(&rustdoc_options),
        no_run: scraped_test.no_run(&rustdoc_options),
        is_multiple_tests: false,
    };
    let res =
        run_test(runnable_test, &rustdoc_options, doctest.supports_color, report_unused_externs);

    if let Err(err) = res {
        match err {
            TestFailure::CompileError => {
                eprint!("Couldn't compile the test.");
            }
            TestFailure::UnexpectedCompilePass => {
                eprint!("Test compiled successfully, but it's marked `compile_fail`.");
            }
            TestFailure::UnexpectedRunPass => {
                eprint!("Test executable succeeded, but it's marked `should_panic`.");
            }
            TestFailure::MissingErrorCodes(codes) => {
                eprint!("Some expected error codes were not found: {codes:?}");
            }
            TestFailure::ExecutionError(err) => {
                eprint!("Couldn't run the test: {err}");
                if err.kind() == io::ErrorKind::PermissionDenied {
                    eprint!(" - maybe your tempdir is mounted with noexec?");
                }
            }
            TestFailure::ExecutionFailure(out) => {
                eprintln!("Test executable failed ({reason}).", reason = out.status);

                // FIXME(#12309): An unfortunate side-effect of capturing the test
                // executable's output is that the relative ordering between the test's
                // stdout and stderr is lost. However, this is better than the
                // alternative: if the test executable inherited the parent's I/O
                // handles the output wouldn't be captured at all, even on success.
                //
                // The ordering could be preserved if the test process' stderr was
                // redirected to stdout, but that functionality does not exist in the
                // standard library, so it may not be portable enough.
                let stdout = str::from_utf8(&out.stdout).unwrap_or_default();
                let stderr = str::from_utf8(&out.stderr).unwrap_or_default();

                if !stdout.is_empty() || !stderr.is_empty() {
                    eprintln!();

                    if !stdout.is_empty() {
                        eprintln!("stdout:\n{stdout}");
                    }

                    if !stderr.is_empty() {
                        eprintln!("stderr:\n{stderr}");
                    }
                }
            }
        }

        panic::resume_unwind(Box::new(()));
    }
    Ok(())
}

#[cfg(test)] // used in tests
impl DocTestVisitor for Vec<usize> {
    fn visit_test(&mut self, _test: String, _config: LangString, rel_line: MdRelLine) {
        self.push(1 + rel_line.offset());
    }
}

#[cfg(test)]
mod tests;
