use std::collections::BTreeMap;
use std::ffi::OsStr;
use std::io::Read;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::{fmt, io};

use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::DiagCtxtHandle;
use rustc_session::config::{
    self, CodegenOptions, CrateType, ErrorOutputType, Externs, Input, JsonUnusedExterns,
    UnstableOptions, get_cmd_lint_options, nightly_options, parse_crate_types_from_list,
    parse_externs, parse_target_triple,
};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
use rustc_session::{EarlyDiagCtxt, getopts};
use rustc_span::FileName;
use rustc_span::edition::Edition;
use rustc_target::spec::TargetTriple;

use crate::core::new_dcx;
use crate::externalfiles::ExternalHtml;
use crate::html::markdown::IdMap;
use crate::html::render::StylePath;
use crate::html::static_files;
use crate::passes::{self, Condition};
use crate::scrape_examples::{AllCallLocations, ScrapeExamplesOptions};
use crate::{html, opts, theme};

#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
pub(crate) enum OutputFormat {
    Json,
    #[default]
    Html,
}

impl OutputFormat {
    pub(crate) fn is_json(&self) -> bool {
        matches!(self, OutputFormat::Json)
    }
}

impl TryFrom<&str> for OutputFormat {
    type Error = String;

    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "json" => Ok(OutputFormat::Json),
            "html" => Ok(OutputFormat::Html),
            _ => Err(format!("unknown output format `{value}`")),
        }
    }
}

/// Either an input crate, markdown file, or nothing (--merge=finalize).
pub(crate) enum InputMode {
    /// The `--merge=finalize` step does not need an input crate to rustdoc.
    NoInputMergeFinalize,
    /// A crate or markdown file.
    HasFile(Input),
}

/// Configuration options for rustdoc.
#[derive(Clone)]
pub(crate) struct Options {
    // Basic options / Options passed directly to rustc
    /// The name of the crate being documented.
    pub(crate) crate_name: Option<String>,
    /// Whether or not this is a bin crate
    pub(crate) bin_crate: bool,
    /// Whether or not this is a proc-macro crate
    pub(crate) proc_macro_crate: bool,
    /// How to format errors and warnings.
    pub(crate) error_format: ErrorOutputType,
    /// Width of output buffer to truncate errors appropriately.
    pub(crate) diagnostic_width: Option<usize>,
    /// Library search paths to hand to the compiler.
    pub(crate) libs: Vec<SearchPath>,
    /// Library search paths strings to hand to the compiler.
    pub(crate) lib_strs: Vec<String>,
    /// The list of external crates to link against.
    pub(crate) externs: Externs,
    /// The list of external crates strings to link against.
    pub(crate) extern_strs: Vec<String>,
    /// List of `cfg` flags to hand to the compiler. Always includes `rustdoc`.
    pub(crate) cfgs: Vec<String>,
    /// List of check cfg flags to hand to the compiler.
    pub(crate) check_cfgs: Vec<String>,
    /// Codegen options to hand to the compiler.
    pub(crate) codegen_options: CodegenOptions,
    /// Codegen options strings to hand to the compiler.
    pub(crate) codegen_options_strs: Vec<String>,
    /// Unstable (`-Z`) options to pass to the compiler.
    pub(crate) unstable_opts: UnstableOptions,
    /// Unstable (`-Z`) options strings to pass to the compiler.
    pub(crate) unstable_opts_strs: Vec<String>,
    /// The target used to compile the crate against.
    pub(crate) target: TargetTriple,
    /// Edition used when reading the crate. Defaults to "2015". Also used by default when
    /// compiling doctests from the crate.
    pub(crate) edition: Edition,
    /// The path to the sysroot. Used during the compilation process.
    pub(crate) maybe_sysroot: Option<PathBuf>,
    /// Lint information passed over the command-line.
    pub(crate) lint_opts: Vec<(String, Level)>,
    /// Whether to ask rustc to describe the lints it knows.
    pub(crate) describe_lints: bool,
    /// What level to cap lints at.
    pub(crate) lint_cap: Option<Level>,

    // Options specific to running doctests
    /// Whether we should run doctests instead of generating docs.
    pub(crate) should_test: bool,
    /// List of arguments to pass to the test harness, if running tests.
    pub(crate) test_args: Vec<String>,
    /// The working directory in which to run tests.
    pub(crate) test_run_directory: Option<PathBuf>,
    /// Optional path to persist the doctest executables to, defaults to a
    /// temporary directory if not set.
    pub(crate) persist_doctests: Option<PathBuf>,
    /// Runtool to run doctests with
    pub(crate) runtool: Option<String>,
    /// Arguments to pass to the runtool
    pub(crate) runtool_args: Vec<String>,
    /// Whether to allow ignoring doctests on a per-target basis
    /// For example, using ignore-foo to ignore running the doctest on any target that
    /// contains "foo" as a substring
    pub(crate) enable_per_target_ignores: bool,
    /// Do not run doctests, compile them if should_test is active.
    pub(crate) no_run: bool,
    /// What sources are being mapped.
    pub(crate) remap_path_prefix: Vec<(PathBuf, PathBuf)>,

    /// The path to a rustc-like binary to build tests with. If not set, we
    /// default to loading from `$sysroot/bin/rustc`.
    pub(crate) test_builder: Option<PathBuf>,

    /// Run these wrapper instead of rustc directly
    pub(crate) test_builder_wrappers: Vec<PathBuf>,

    // Options that affect the documentation process
    /// Whether to run the `calculate-doc-coverage` pass, which counts the number of public items
    /// with and without documentation.
    pub(crate) show_coverage: bool,

    // Options that alter generated documentation pages
    /// Crate version to note on the sidebar of generated docs.
    pub(crate) crate_version: Option<String>,
    /// The format that we output when rendering.
    ///
    /// Currently used only for the `--show-coverage` option.
    pub(crate) output_format: OutputFormat,
    /// If this option is set to `true`, rustdoc will only run checks and not generate
    /// documentation.
    pub(crate) run_check: bool,
    /// Whether doctests should emit unused externs
    pub(crate) json_unused_externs: JsonUnusedExterns,
    /// Whether to skip capturing stdout and stderr of tests.
    pub(crate) nocapture: bool,

    /// Configuration for scraping examples from the current crate. If this option is Some(..) then
    /// the compiler will scrape examples and not generate documentation.
    pub(crate) scrape_examples_options: Option<ScrapeExamplesOptions>,

    /// Note: this field is duplicated in `RenderOptions` because it's useful
    /// to have it in both places.
    pub(crate) unstable_features: rustc_feature::UnstableFeatures,

    /// All commandline args used to invoke the compiler, with @file args fully expanded.
    /// This will only be used within debug info, e.g. in the pdb file on windows
    /// This is mainly useful for other tools that reads that debuginfo to figure out
    /// how to call the compiler with the same arguments.
    pub(crate) expanded_args: Vec<String>,
}

impl fmt::Debug for Options {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        struct FmtExterns<'a>(&'a Externs);

        impl<'a> fmt::Debug for FmtExterns<'a> {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                f.debug_map().entries(self.0.iter()).finish()
            }
        }

        f.debug_struct("Options")
            .field("crate_name", &self.crate_name)
            .field("bin_crate", &self.bin_crate)
            .field("proc_macro_crate", &self.proc_macro_crate)
            .field("error_format", &self.error_format)
            .field("libs", &self.libs)
            .field("externs", &FmtExterns(&self.externs))
            .field("cfgs", &self.cfgs)
            .field("check-cfgs", &self.check_cfgs)
            .field("codegen_options", &"...")
            .field("unstable_options", &"...")
            .field("target", &self.target)
            .field("edition", &self.edition)
            .field("maybe_sysroot", &self.maybe_sysroot)
            .field("lint_opts", &self.lint_opts)
            .field("describe_lints", &self.describe_lints)
            .field("lint_cap", &self.lint_cap)
            .field("should_test", &self.should_test)
            .field("test_args", &self.test_args)
            .field("test_run_directory", &self.test_run_directory)
            .field("persist_doctests", &self.persist_doctests)
            .field("show_coverage", &self.show_coverage)
            .field("crate_version", &self.crate_version)
            .field("runtool", &self.runtool)
            .field("runtool_args", &self.runtool_args)
            .field("enable-per-target-ignores", &self.enable_per_target_ignores)
            .field("run_check", &self.run_check)
            .field("no_run", &self.no_run)
            .field("test_builder_wrappers", &self.test_builder_wrappers)
            .field("remap-file-prefix", &self.remap_path_prefix)
            .field("nocapture", &self.nocapture)
            .field("scrape_examples_options", &self.scrape_examples_options)
            .field("unstable_features", &self.unstable_features)
            .finish()
    }
}

/// Configuration options for the HTML page-creation process.
#[derive(Clone, Debug)]
pub(crate) struct RenderOptions {
    /// Output directory to generate docs into. Defaults to `doc`.
    pub(crate) output: PathBuf,
    /// External files to insert into generated pages.
    pub(crate) external_html: ExternalHtml,
    /// A pre-populated `IdMap` with the default headings and any headings added by Markdown files
    /// processed by `external_html`.
    pub(crate) id_map: IdMap,
    /// If present, playground URL to use in the "Run" button added to code samples.
    ///
    /// Be aware: This option can come both from the CLI and from crate attributes!
    pub(crate) playground_url: Option<String>,
    /// What sorting mode to use for module pages.
    /// `ModuleSorting::Alphabetical` by default.
    pub(crate) module_sorting: ModuleSorting,
    /// List of themes to extend the docs with. Original argument name is included to assist in
    /// displaying errors if it fails a theme check.
    pub(crate) themes: Vec<StylePath>,
    /// If present, CSS file that contains rules to add to the default CSS.
    pub(crate) extension_css: Option<PathBuf>,
    /// A map of crate names to the URL to use instead of querying the crate's `html_root_url`.
    pub(crate) extern_html_root_urls: BTreeMap<String, String>,
    /// Whether to give precedence to `html_root_url` or `--extern-html-root-url`.
    pub(crate) extern_html_root_takes_precedence: bool,
    /// A map of the default settings (values are as for DOM storage API). Keys should lack the
    /// `rustdoc-` prefix.
    pub(crate) default_settings: FxIndexMap<String, String>,
    /// If present, suffix added to CSS/JavaScript files when referencing them in generated pages.
    pub(crate) resource_suffix: String,
    /// Whether to create an index page in the root of the output directory. If this is true but
    /// `enable_index_page` is None, generate a static listing of crates instead.
    pub(crate) enable_index_page: bool,
    /// A file to use as the index page at the root of the output directory. Overrides
    /// `enable_index_page` to be true if set.
    pub(crate) index_page: Option<PathBuf>,
    /// An optional path to use as the location of static files. If not set, uses combinations of
    /// `../` to reach the documentation root.
    pub(crate) static_root_path: Option<String>,

    // Options specific to reading standalone Markdown files
    /// Whether to generate a table of contents on the output file when reading a standalone
    /// Markdown file.
    pub(crate) markdown_no_toc: bool,
    /// Additional CSS files to link in pages generated from standalone Markdown files.
    pub(crate) markdown_css: Vec<String>,
    /// If present, playground URL to use in the "Run" button added to code samples generated from
    /// standalone Markdown files. If not present, `playground_url` is used.
    pub(crate) markdown_playground_url: Option<String>,
    /// Document items that have lower than `pub` visibility.
    pub(crate) document_private: bool,
    /// Document items that have `doc(hidden)`.
    pub(crate) document_hidden: bool,
    /// If `true`, generate a JSON file in the crate folder instead of HTML redirection files.
    pub(crate) generate_redirect_map: bool,
    /// Show the memory layout of types in the docs.
    pub(crate) show_type_layout: bool,
    /// Note: this field is duplicated in `Options` because it's useful to have
    /// it in both places.
    pub(crate) unstable_features: rustc_feature::UnstableFeatures,
    pub(crate) emit: Vec<EmitType>,
    /// If `true`, HTML source pages will generate links for items to their definition.
    pub(crate) generate_link_to_definition: bool,
    /// Set of function-call locations to include as examples
    pub(crate) call_locations: AllCallLocations,
    /// If `true`, Context::init will not emit shared files.
    pub(crate) no_emit_shared: bool,
    /// If `true`, HTML source code pages won't be generated.
    pub(crate) html_no_source: bool,
    /// This field is only used for the JSON output. If it's set to true, no file will be created
    /// and content will be displayed in stdout directly.
    pub(crate) output_to_stdout: bool,
    /// Whether we should read or write rendered cross-crate info in the doc root.
    pub(crate) should_merge: ShouldMerge,
    /// Path to crate-info for external crates.
    pub(crate) include_parts_dir: Vec<PathToParts>,
    /// Where to write crate-info
    pub(crate) parts_out_dir: Option<PathToParts>,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum ModuleSorting {
    DeclarationOrder,
    Alphabetical,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum EmitType {
    Unversioned,
    Toolchain,
    InvocationSpecific,
}

impl FromStr for EmitType {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use EmitType::*;
        match s {
            "unversioned-shared-resources" => Ok(Unversioned),
            "toolchain-shared-resources" => Ok(Toolchain),
            "invocation-specific" => Ok(InvocationSpecific),
            _ => Err(()),
        }
    }
}

impl RenderOptions {
    pub(crate) fn should_emit_crate(&self) -> bool {
        self.emit.is_empty() || self.emit.contains(&EmitType::InvocationSpecific)
    }
}

/// Create the input (string or file path)
///
/// Warning: Return an unrecoverable error in case of error!
fn make_input(early_dcx: &EarlyDiagCtxt, input: &str) -> Input {
    if input == "-" {
        let mut src = String::new();
        if io::stdin().read_to_string(&mut src).is_err() {
            // Immediately stop compilation if there was an issue reading
            // the input (for example if the input stream is not UTF-8).
            early_dcx.early_fatal("couldn't read from stdin, as it did not contain valid UTF-8");
        }
        Input::Str { name: FileName::anon_source_code(&src), input: src }
    } else {
        Input::File(PathBuf::from(input))
    }
}

impl Options {
    /// Parses the given command-line for options. If an error message or other early-return has
    /// been printed, returns `Err` with the exit code.
    pub(crate) fn from_matches(
        early_dcx: &mut EarlyDiagCtxt,
        matches: &getopts::Matches,
        args: Vec<String>,
    ) -> Option<(InputMode, Options, RenderOptions)> {
        // Check for unstable options.
        nightly_options::check_nightly_options(early_dcx, matches, &opts());

        if args.is_empty() || matches.opt_present("h") || matches.opt_present("help") {
            crate::usage("rustdoc");
            return None;
        } else if matches.opt_present("version") {
            rustc_driver::version!(&early_dcx, "rustdoc", matches);
            return None;
        }

        if rustc_driver::describe_flag_categories(early_dcx, matches) {
            return None;
        }

        let color = config::parse_color(early_dcx, matches);
        let config::JsonConfig { json_rendered, json_unused_externs, json_color, .. } =
            config::parse_json(early_dcx, matches);
        let error_format =
            config::parse_error_format(early_dcx, matches, color, json_color, json_rendered);
        let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default();

        let codegen_options = CodegenOptions::build(early_dcx, matches);
        let unstable_opts = UnstableOptions::build(early_dcx, matches);

        let remap_path_prefix = match parse_remap_path_prefix(matches) {
            Ok(prefix_mappings) => prefix_mappings,
            Err(err) => {
                early_dcx.early_fatal(err);
            }
        };

        let dcx = new_dcx(error_format, None, diagnostic_width, &unstable_opts);
        let dcx = dcx.handle();

        // check for deprecated options
        check_deprecated_options(matches, dcx);

        if matches.opt_strs("passes") == ["list"] {
            println!("Available passes for running rustdoc:");
            for pass in passes::PASSES {
                println!("{:>20} - {}", pass.name, pass.description);
            }
            println!("\nDefault passes for rustdoc:");
            for p in passes::DEFAULT_PASSES {
                print!("{:>20}", p.pass.name);
                println_condition(p.condition);
            }

            if nightly_options::match_is_nightly_build(matches) {
                println!("\nPasses run with `--show-coverage`:");
                for p in passes::COVERAGE_PASSES {
                    print!("{:>20}", p.pass.name);
                    println_condition(p.condition);
                }
            }

            fn println_condition(condition: Condition) {
                use Condition::*;
                match condition {
                    Always => println!(),
                    WhenDocumentPrivate => println!("  (when --document-private-items)"),
                    WhenNotDocumentPrivate => println!("  (when not --document-private-items)"),
                    WhenNotDocumentHidden => println!("  (when not --document-hidden-items)"),
                }
            }

            return None;
        }

        let mut emit = Vec::new();
        for list in matches.opt_strs("emit") {
            for kind in list.split(',') {
                match kind.parse() {
                    Ok(kind) => emit.push(kind),
                    Err(()) => dcx.fatal(format!("unrecognized emission type: {kind}")),
                }
            }
        }

        // check for `--output-format=json`
        if !matches!(matches.opt_str("output-format").as_deref(), None | Some("html"))
            && !matches.opt_present("show-coverage")
            && !nightly_options::is_unstable_enabled(matches)
        {
            dcx.fatal(
                "the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/76578)",
            );
        }

        let to_check = matches.opt_strs("check-theme");
        if !to_check.is_empty() {
            let mut content =
                std::str::from_utf8(static_files::STATIC_FILES.rustdoc_css.bytes).unwrap();
            if let Some((_, inside)) = content.split_once("/* Begin theme: light */") {
                content = inside;
            }
            if let Some((inside, _)) = content.split_once("/* End theme: light */") {
                content = inside;
            }
            let paths = match theme::load_css_paths(content) {
                Ok(p) => p,
                Err(e) => dcx.fatal(e),
            };
            let mut errors = 0;

            println!("rustdoc: [check-theme] Starting tests! (Ignoring all other arguments)");
            for theme_file in to_check.iter() {
                print!(" - Checking \"{theme_file}\"...");
                let (success, differences) = theme::test_theme_against(theme_file, &paths, dcx);
                if !differences.is_empty() || !success {
                    println!(" FAILED");
                    errors += 1;
                    if !differences.is_empty() {
                        println!("{}", differences.join("\n"));
                    }
                } else {
                    println!(" OK");
                }
            }
            if errors != 0 {
                dcx.fatal("[check-theme] one or more tests failed");
            }
            return None;
        }

        let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);

        let input = if describe_lints {
            InputMode::HasFile(make_input(early_dcx, ""))
        } else {
            match matches.free.as_slice() {
                [] if matches.opt_str("merge").as_deref() == Some("finalize") => {
                    InputMode::NoInputMergeFinalize
                }
                [] => dcx.fatal("missing file operand"),
                [input] => InputMode::HasFile(make_input(early_dcx, input)),
                _ => dcx.fatal("too many file operands"),
            }
        };

        let externs = parse_externs(early_dcx, matches, &unstable_opts);
        let extern_html_root_urls = match parse_extern_html_roots(matches) {
            Ok(ex) => ex,
            Err(err) => dcx.fatal(err),
        };

        let parts_out_dir =
            match matches.opt_str("parts-out-dir").map(|p| PathToParts::from_flag(p)).transpose() {
                Ok(parts_out_dir) => parts_out_dir,
                Err(e) => dcx.fatal(e),
            };
        let include_parts_dir = match parse_include_parts_dir(matches) {
            Ok(include_parts_dir) => include_parts_dir,
            Err(e) => dcx.fatal(e),
        };

        let default_settings: Vec<Vec<(String, String)>> = vec![
            matches
                .opt_str("default-theme")
                .iter()
                .flat_map(|theme| {
                    vec![
                        ("use-system-theme".to_string(), "false".to_string()),
                        ("theme".to_string(), theme.to_string()),
                    ]
                })
                .collect(),
            matches
                .opt_strs("default-setting")
                .iter()
                .map(|s| match s.split_once('=') {
                    None => (s.clone(), "true".to_string()),
                    Some((k, v)) => (k.to_string(), v.to_string()),
                })
                .collect(),
        ];
        let default_settings = default_settings
            .into_iter()
            .flatten()
            .map(
                // The keys here become part of `data-` attribute names in the generated HTML.  The
                // browser does a strange mapping when converting them into attributes on the
                // `dataset` property on the DOM HTML Node:
                //   https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset
                //
                // The original key values we have are the same as the DOM storage API keys and the
                // command line options, so contain `-`.  Our JavaScript needs to be able to look
                // these values up both in `dataset` and in the storage API, so it needs to be able
                // to convert the names back and forth.  Despite doing this kebab-case to
                // StudlyCaps transformation automatically, the JS DOM API does not provide a
                // mechanism for doing just the transformation on a string.  So we want to avoid
                // the StudlyCaps representation in the `dataset` property.
                //
                // We solve this by replacing all the `-`s with `_`s.  We do that here, when we
                // generate the `data-` attributes, and in the JS, when we look them up.  (See
                // `getSettingValue` in `storage.js.`) Converting `-` to `_` is simple in JS.
                //
                // The values will be HTML-escaped by the default Tera escaping.
                |(k, v)| (k.replace('-', "_"), v),
            )
            .collect();

        let test_args = matches.opt_strs("test-args");
        let test_args: Vec<String> =
            test_args.iter().flat_map(|s| s.split_whitespace()).map(|s| s.to_string()).collect();

        let should_test = matches.opt_present("test");
        let no_run = matches.opt_present("no-run");

        if !should_test && no_run {
            dcx.fatal("the `--test` flag must be passed to enable `--no-run`");
        }

        let mut output_to_stdout = false;
        let test_builder_wrappers =
            matches.opt_strs("test-builder-wrapper").iter().map(PathBuf::from).collect();
        let output = match (matches.opt_str("out-dir"), matches.opt_str("output")) {
            (Some(_), Some(_)) => {
                dcx.fatal("cannot use both 'out-dir' and 'output' at once");
            }
            (Some(out_dir), None) | (None, Some(out_dir)) => {
                output_to_stdout = out_dir == "-";
                PathBuf::from(out_dir)
            }
            (None, None) => PathBuf::from("doc"),
        };

        let cfgs = matches.opt_strs("cfg");
        let check_cfgs = matches.opt_strs("check-cfg");

        let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s));

        if let Some(ref p) = extension_css {
            if !p.is_file() {
                dcx.fatal("option --extend-css argument must be a file");
            }
        }

        let mut themes = Vec::new();
        if matches.opt_present("theme") {
            let mut content =
                std::str::from_utf8(static_files::STATIC_FILES.rustdoc_css.bytes).unwrap();
            if let Some((_, inside)) = content.split_once("/* Begin theme: light */") {
                content = inside;
            }
            if let Some((inside, _)) = content.split_once("/* End theme: light */") {
                content = inside;
            }
            let paths = match theme::load_css_paths(content) {
                Ok(p) => p,
                Err(e) => dcx.fatal(e),
            };

            for (theme_file, theme_s) in
                matches.opt_strs("theme").iter().map(|s| (PathBuf::from(&s), s.to_owned()))
            {
                if !theme_file.is_file() {
                    dcx.struct_fatal(format!("invalid argument: \"{theme_s}\""))
                        .with_help("arguments to --theme must be files")
                        .emit();
                }
                if theme_file.extension() != Some(OsStr::new("css")) {
                    dcx.struct_fatal(format!("invalid argument: \"{theme_s}\""))
                        .with_help("arguments to --theme must have a .css extension")
                        .emit();
                }
                let (success, ret) = theme::test_theme_against(&theme_file, &paths, dcx);
                if !success {
                    dcx.fatal(format!("error loading theme file: \"{theme_s}\""));
                } else if !ret.is_empty() {
                    dcx.struct_warn(format!(
                        "theme file \"{theme_s}\" is missing CSS rules from the default theme",
                    ))
                    .with_warn("the theme may appear incorrect when loaded")
                    .with_help(format!(
                        "to see what rules are missing, call `rustdoc --check-theme \"{theme_s}\"`",
                    ))
                    .emit();
                }
                themes.push(StylePath { path: theme_file });
            }
        }

        let edition = config::parse_crate_edition(early_dcx, matches);

        let mut id_map = html::markdown::IdMap::new();
        let Some(external_html) = ExternalHtml::load(
            &matches.opt_strs("html-in-header"),
            &matches.opt_strs("html-before-content"),
            &matches.opt_strs("html-after-content"),
            &matches.opt_strs("markdown-before-content"),
            &matches.opt_strs("markdown-after-content"),
            nightly_options::match_is_nightly_build(matches),
            dcx,
            &mut id_map,
            edition,
            &None,
        ) else {
            dcx.fatal("`ExternalHtml::load` failed");
        };

        match matches.opt_str("r").as_deref() {
            Some("rust") | None => {}
            Some(s) => dcx.fatal(format!("unknown input format: {s}")),
        }

        let index_page = matches.opt_str("index-page").map(|s| PathBuf::from(&s));
        if let Some(ref index_page) = index_page {
            if !index_page.is_file() {
                dcx.fatal("option `--index-page` argument must be a file");
            }
        }

        let target = parse_target_triple(early_dcx, matches);
        let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);

        let sysroot = match &maybe_sysroot {
            Some(s) => s.clone(),
            None => {
                rustc_session::filesearch::get_or_default_sysroot().expect("Failed finding sysroot")
            }
        };

        let libs = matches
            .opt_strs("L")
            .iter()
            .map(|s| {
                SearchPath::from_cli_opt(
                    &sysroot,
                    &target,
                    early_dcx,
                    s,
                    #[allow(rustc::bad_opt_access)] // we have no `Session` here
                    unstable_opts.unstable_options,
                )
            })
            .collect();

        let show_coverage = matches.opt_present("show-coverage");

        let crate_types = match parse_crate_types_from_list(matches.opt_strs("crate-type")) {
            Ok(types) => types,
            Err(e) => {
                dcx.fatal(format!("unknown crate type: {e}"));
            }
        };

        let output_format = match matches.opt_str("output-format") {
            Some(s) => match OutputFormat::try_from(s.as_str()) {
                Ok(out_fmt) => {
                    if !out_fmt.is_json() && show_coverage {
                        dcx.fatal(
                            "html output format isn't supported for the --show-coverage option",
                        );
                    }
                    out_fmt
                }
                Err(e) => dcx.fatal(e),
            },
            None => OutputFormat::default(),
        };
        let crate_name = matches.opt_str("crate-name");
        let bin_crate = crate_types.contains(&CrateType::Executable);
        let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
        let playground_url = matches.opt_str("playground-url");
        let module_sorting = if matches.opt_present("sort-modules-by-appearance") {
            ModuleSorting::DeclarationOrder
        } else {
            ModuleSorting::Alphabetical
        };
        let resource_suffix = matches.opt_str("resource-suffix").unwrap_or_default();
        let markdown_no_toc = matches.opt_present("markdown-no-toc");
        let markdown_css = matches.opt_strs("markdown-css");
        let markdown_playground_url = matches.opt_str("markdown-playground-url");
        let crate_version = matches.opt_str("crate-version");
        let enable_index_page = matches.opt_present("enable-index-page") || index_page.is_some();
        let static_root_path = matches.opt_str("static-root-path");
        let test_run_directory = matches.opt_str("test-run-directory").map(PathBuf::from);
        let persist_doctests = matches.opt_str("persist-doctests").map(PathBuf::from);
        let test_builder = matches.opt_str("test-builder").map(PathBuf::from);
        let codegen_options_strs = matches.opt_strs("C");
        let unstable_opts_strs = matches.opt_strs("Z");
        let lib_strs = matches.opt_strs("L");
        let extern_strs = matches.opt_strs("extern");
        let runtool = matches.opt_str("runtool");
        let runtool_args = matches.opt_strs("runtool-arg");
        let enable_per_target_ignores = matches.opt_present("enable-per-target-ignores");
        let document_private = matches.opt_present("document-private-items");
        let document_hidden = matches.opt_present("document-hidden-items");
        let run_check = matches.opt_present("check");
        let generate_redirect_map = matches.opt_present("generate-redirect-map");
        let show_type_layout = matches.opt_present("show-type-layout");
        let nocapture = matches.opt_present("nocapture");
        let generate_link_to_definition = matches.opt_present("generate-link-to-definition");
        let extern_html_root_takes_precedence =
            matches.opt_present("extern-html-root-takes-precedence");
        let html_no_source = matches.opt_present("html-no-source");
        let should_merge = match parse_merge(matches) {
            Ok(result) => result,
            Err(e) => dcx.fatal(format!("--merge option error: {e}")),
        };

        if generate_link_to_definition && (show_coverage || output_format != OutputFormat::Html) {
            dcx.struct_warn(
                "`--generate-link-to-definition` option can only be used with HTML output format",
            )
            .with_note("`--generate-link-to-definition` option will be ignored")
            .emit();
        }

        let scrape_examples_options = ScrapeExamplesOptions::new(matches, dcx);
        let with_examples = matches.opt_strs("with-examples");
        let call_locations = crate::scrape_examples::load_call_locations(with_examples, dcx);

        let unstable_features =
            rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
        let options = Options {
            bin_crate,
            proc_macro_crate,
            error_format,
            diagnostic_width,
            libs,
            lib_strs,
            externs,
            extern_strs,
            cfgs,
            check_cfgs,
            codegen_options,
            codegen_options_strs,
            unstable_opts,
            unstable_opts_strs,
            target,
            edition,
            maybe_sysroot,
            lint_opts,
            describe_lints,
            lint_cap,
            should_test,
            test_args,
            show_coverage,
            crate_version,
            test_run_directory,
            persist_doctests,
            runtool,
            runtool_args,
            enable_per_target_ignores,
            test_builder,
            run_check,
            no_run,
            test_builder_wrappers,
            remap_path_prefix,
            nocapture,
            crate_name,
            output_format,
            json_unused_externs,
            scrape_examples_options,
            unstable_features,
            expanded_args: args,
        };
        let render_options = RenderOptions {
            output,
            external_html,
            id_map,
            playground_url,
            module_sorting,
            themes,
            extension_css,
            extern_html_root_urls,
            extern_html_root_takes_precedence,
            default_settings,
            resource_suffix,
            enable_index_page,
            index_page,
            static_root_path,
            markdown_no_toc,
            markdown_css,
            markdown_playground_url,
            document_private,
            document_hidden,
            generate_redirect_map,
            show_type_layout,
            unstable_features,
            emit,
            generate_link_to_definition,
            call_locations,
            no_emit_shared: false,
            html_no_source,
            output_to_stdout,
            should_merge,
            include_parts_dir,
            parts_out_dir,
        };
        Some((input, options, render_options))
    }
}

/// Returns `true` if the file given as `self.input` is a Markdown file.
pub(crate) fn markdown_input(input: &Input) -> Option<&Path> {
    input.opt_path().filter(|p| matches!(p.extension(), Some(e) if e == "md" || e == "markdown"))
}

fn parse_remap_path_prefix(
    matches: &getopts::Matches,
) -> Result<Vec<(PathBuf, PathBuf)>, &'static str> {
    matches
        .opt_strs("remap-path-prefix")
        .into_iter()
        .map(|remap| {
            remap
                .rsplit_once('=')
                .ok_or("--remap-path-prefix must contain '=' between FROM and TO")
                .map(|(from, to)| (PathBuf::from(from), PathBuf::from(to)))
        })
        .collect()
}

/// Prints deprecation warnings for deprecated options
fn check_deprecated_options(matches: &getopts::Matches, dcx: DiagCtxtHandle<'_>) {
    let deprecated_flags = [];

    for &flag in deprecated_flags.iter() {
        if matches.opt_present(flag) {
            dcx.struct_warn(format!("the `{flag}` flag is deprecated"))
                .with_note(
                    "see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \
                    for more information",
                )
                .emit();
        }
    }

    let removed_flags = ["plugins", "plugin-path", "no-defaults", "passes", "input-format"];

    for &flag in removed_flags.iter() {
        if matches.opt_present(flag) {
            let mut err = dcx.struct_warn(format!("the `{flag}` flag no longer functions"));
            err.note(
                "see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \
                for more information",
            );

            if flag == "no-defaults" || flag == "passes" {
                err.help("you may want to use --document-private-items");
            } else if flag == "plugins" || flag == "plugin-path" {
                err.warn("see CVE-2018-1000622");
            }

            err.emit();
        }
    }
}

/// Extracts `--extern-html-root-url` arguments from `matches` and returns a map of crate names to
/// the given URLs. If an `--extern-html-root-url` argument was ill-formed, returns an error
/// describing the issue.
fn parse_extern_html_roots(
    matches: &getopts::Matches,
) -> Result<BTreeMap<String, String>, &'static str> {
    let mut externs = BTreeMap::new();
    for arg in &matches.opt_strs("extern-html-root-url") {
        let (name, url) =
            arg.split_once('=').ok_or("--extern-html-root-url must be of the form name=url")?;
        externs.insert(name.to_string(), url.to_string());
    }
    Ok(externs)
}

/// Path directly to crate-info file.
///
/// For example, `/home/user/project/target/doc.parts/<crate>/crate-info`.
#[derive(Clone, Debug)]
pub(crate) struct PathToParts(pub(crate) PathBuf);

impl PathToParts {
    fn from_flag(path: String) -> Result<PathToParts, String> {
        let mut path = PathBuf::from(path);
        // check here is for diagnostics
        if path.exists() && !path.is_dir() {
            Err(format!(
                "--parts-out-dir and --include-parts-dir expect directories, found: {}",
                path.display(),
            ))
        } else {
            // if it doesn't exist, we'll create it. worry about that in write_shared
            path.push("crate-info");
            Ok(PathToParts(path))
        }
    }
}

/// Reports error if --include-parts-dir / crate-info is not a file
fn parse_include_parts_dir(m: &getopts::Matches) -> Result<Vec<PathToParts>, String> {
    let mut ret = Vec::new();
    for p in m.opt_strs("include-parts-dir") {
        let p = PathToParts::from_flag(p)?;
        // this is just for diagnostic
        if !p.0.is_file() {
            return Err(format!("--include-parts-dir expected {} to be a file", p.0.display()));
        }
        ret.push(p);
    }
    Ok(ret)
}

/// Controls merging of cross-crate information
#[derive(Debug, Clone)]
pub(crate) struct ShouldMerge {
    /// Should we append to existing cci in the doc root
    pub(crate) read_rendered_cci: bool,
    /// Should we write cci to the doc root
    pub(crate) write_rendered_cci: bool,
}

/// Extracts read_rendered_cci and write_rendered_cci from command line arguments, or
/// reports an error if an invalid option was provided
fn parse_merge(m: &getopts::Matches) -> Result<ShouldMerge, &'static str> {
    match m.opt_str("merge").as_deref() {
        // default = read-write
        None => Ok(ShouldMerge { read_rendered_cci: true, write_rendered_cci: true }),
        Some("none") if m.opt_present("include-parts-dir") => {
            Err("--include-parts-dir not allowed if --merge=none")
        }
        Some("none") => Ok(ShouldMerge { read_rendered_cci: false, write_rendered_cci: false }),
        Some("shared") if m.opt_present("parts-out-dir") || m.opt_present("include-parts-dir") => {
            Err("--parts-out-dir and --include-parts-dir not allowed if --merge=shared")
        }
        Some("shared") => Ok(ShouldMerge { read_rendered_cci: true, write_rendered_cci: true }),
        Some("finalize") if m.opt_present("parts-out-dir") => {
            Err("--parts-out-dir not allowed if --merge=finalize")
        }
        Some("finalize") => Ok(ShouldMerge { read_rendered_cci: false, write_rendered_cci: true }),
        Some(_) => Err("argument to --merge must be `none`, `shared`, or `finalize`"),
    }
}
