//! Doctest functionality used only for doctests in `.md` Markdown files.

use std::fs::read_to_string;
use std::sync::{Arc, Mutex};

use rustc_session::config::Input;
use rustc_span::FileName;
use tempfile::tempdir;

use super::{
    CreateRunnableDocTests, DocTestVisitor, GlobalTestOptions, ScrapedDocTest, generate_args_file,
};
use crate::config::Options;
use crate::html::markdown::{ErrorCodes, LangString, MdRelLine, find_testable_code};

struct MdCollector {
    tests: Vec<ScrapedDocTest>,
    cur_path: Vec<String>,
    filename: FileName,
}

impl DocTestVisitor for MdCollector {
    fn visit_test(&mut self, test: String, config: LangString, rel_line: MdRelLine) {
        let filename = self.filename.clone();
        // First line of Markdown is line 1.
        let line = 1 + rel_line.offset();
        self.tests.push(ScrapedDocTest::new(filename, line, self.cur_path.clone(), config, test));
    }

    fn visit_header(&mut self, name: &str, level: u32) {
        // We use these headings as test names, so it's good if
        // they're valid identifiers.
        let name = name
            .chars()
            .enumerate()
            .map(|(i, c)| {
                if (i == 0 && rustc_lexer::is_id_start(c))
                    || (i != 0 && rustc_lexer::is_id_continue(c))
                {
                    c
                } else {
                    '_'
                }
            })
            .collect::<String>();

        // Here we try to efficiently assemble the header titles into the
        // test name in the form of `h1::h2::h3::h4::h5::h6`.
        //
        // Suppose that originally `self.cur_path` contains `[h1, h2, h3]`...
        let level = level as usize;
        if level <= self.cur_path.len() {
            // ... Consider `level == 2`. All headers in the lower levels
            // are irrelevant in this new level. So we should reset
            // `self.names` to contain headers until <h2>, and replace that
            // slot with the new name: `[h1, name]`.
            self.cur_path.truncate(level);
            self.cur_path[level - 1] = name;
        } else {
            // ... On the other hand, consider `level == 5`. This means we
            // need to extend `self.names` to contain five headers. We fill
            // in the missing level (<h4>) with `_`. Thus `self.names` will
            // become `[h1, h2, h3, "_", name]`.
            if level - 1 > self.cur_path.len() {
                self.cur_path.resize(level - 1, "_".to_owned());
            }
            self.cur_path.push(name);
        }
    }
}

/// Runs any tests/code examples in the markdown file `options.input`.
pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> {
    let input_str = match input {
        Input::File(path) => {
            read_to_string(path).map_err(|err| format!("{}: {err}", path.display()))?
        }
        Input::Str { name: _, input } => input.clone(),
    };

    // Obviously not a real crate name, but close enough for purposes of doctests.
    let crate_name = input.filestem().to_string();
    let temp_dir =
        tempdir().map_err(|error| format!("failed to create temporary directory: {error:?}"))?;
    let args_file = temp_dir.path().join("rustdoc-cfgs");
    generate_args_file(&args_file, &options)?;

    let opts = GlobalTestOptions {
        crate_name,
        no_crate_inject: true,
        insert_indent_space: false,
        attrs: vec![],
        args_file,
    };

    let mut md_collector = MdCollector {
        tests: vec![],
        cur_path: vec![],
        filename: input
            .opt_path()
            .map(ToOwned::to_owned)
            .map(FileName::from)
            .unwrap_or(FileName::Custom("input".to_owned())),
    };
    let codes = ErrorCodes::from(options.unstable_features.is_nightly_build());

    find_testable_code(
        &input_str,
        &mut md_collector,
        codes,
        options.enable_per_target_ignores,
        None,
    );

    let mut collector = CreateRunnableDocTests::new(options.clone(), opts);
    md_collector.tests.into_iter().for_each(|t| collector.add_test(t));
    let CreateRunnableDocTests { opts, rustdoc_options, standalone_tests, mergeable_tests, .. } =
        collector;
    crate::doctest::run_tests(
        opts,
        &rustdoc_options,
        &Arc::new(Mutex::new(Vec::new())),
        standalone_tests,
        mergeable_tests,
    );
    Ok(())
}
