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,
    OptionsTargetModifiers, Sysroot, 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::TargetTuple;

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,
    Doctest,
}

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),
            "doctest" => Ok(OutputFormat::Doctest),
            _ => 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: TargetTuple,
    /// 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) sysroot: Sysroot,
    /// 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) test_runtool: Option<String>,
    /// Arguments to pass to the runtool
    pub(crate) test_runtool_args: Vec<String>,
    /// 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>,

    /// Arguments to be used when compiling doctests.
    pub(crate) doctest_build_args: Vec<String>,

    /// Target modifiers.
    pub(crate) target_modifiers: BTreeMap<OptionsTargetModifiers, String>,
}

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

        impl fmt::Debug for FmtExterns<'_> {
            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("sysroot", &self.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("test_runtool", &self.test_runtool)
            .field("test_runtool_args", &self.test_runtool_args)
            .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>,
    /// disable minification of CSS/JS
    pub(crate) disable_minification: bool,
    /// If `true`, HTML source pages will generate the possibility to expand macros.
    pub(crate) generate_macro_expansion: bool,
}

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

#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) enum EmitType {
    Unversioned,
    Toolchain,
    InvocationSpecific,
    DepInfo(Option<PathBuf>),
}

impl FromStr for EmitType {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "unversioned-shared-resources" => Ok(Self::Unversioned),
            "toolchain-shared-resources" => Ok(Self::Toolchain),
            "invocation-specific" => Ok(Self::InvocationSpecific),
            "dep-info" => Ok(Self::DepInfo(None)),
            option => {
                if let Some(file) = option.strip_prefix("dep-info=") {
                    Ok(Self::DepInfo(Some(Path::new(file).into())))
                } else {
                    Err(())
                }
            }
        }
    }
}

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

    pub(crate) fn dep_info(&self) -> Option<Option<&Path>> {
        for emit in &self.emit {
            if let EmitType::DepInfo(file) = emit {
                return Some(file.as_deref());
            }
        }
        None
    }
}

/// 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, Vec<PathBuf>)> {
        // 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 mut target_modifiers = BTreeMap::<OptionsTargetModifiers, String>::new();
        let codegen_options = CodegenOptions::build(early_dcx, matches, &mut target_modifiers);
        let unstable_opts = UnstableOptions::build(early_dcx, matches, &mut target_modifiers);

        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}")),
                }
            }
        }

        let show_coverage = matches.opt_present("show-coverage");
        let output_format_s = matches.opt_str("output-format");
        let output_format = match output_format_s {
            Some(ref s) => match OutputFormat::try_from(s.as_str()) {
                Ok(out_fmt) => out_fmt,
                Err(e) => dcx.fatal(e),
            },
            None => OutputFormat::default(),
        };

        // check for `--output-format=json`
        match (
            output_format_s.as_ref().map(|_| output_format),
            show_coverage,
            nightly_options::is_unstable_enabled(matches),
        ) {
            (None | Some(OutputFormat::Json), true, _) => {}
            (_, true, _) => {
                dcx.fatal(format!(
                    "`--output-format={}` is not supported for the `--show-coverage` option",
                    output_format_s.unwrap_or_default(),
                ));
            }
            // If `-Zunstable-options` is used, nothing to check after this point.
            (_, false, true) => {}
            (None | Some(OutputFormat::Html), false, _) => {}
            (Some(OutputFormat::Json), false, false) => {
                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)",
                );
            }
            (Some(OutputFormat::Doctest), false, false) => {
                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/134529)",
                );
            }
        }

        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.src_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(PathToParts::from_flag).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));

        let mut loaded_paths = Vec::new();

        if let Some(ref p) = extension_css {
            loaded_paths.push(p.clone());
            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.src_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();
                }
                loaded_paths.push(theme_file.clone());
                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,
            &mut loaded_paths,
        ) 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
            && !index_page.is_file()
        {
            dcx.fatal("option `--index-page` argument must be a file");
        }

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

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

        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 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 test_runtool = matches.opt_str("test-runtool");
        let test_runtool_args = matches.opt_strs("test-runtool-arg");
        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 generate_macro_expansion = matches.opt_present("generate-macro-expansion");
        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();
        }
        if generate_macro_expansion && (show_coverage || output_format != OutputFormat::Html) {
            dcx.struct_warn(
                "`--generate-macro-expansion` option can only be used with HTML output format",
            )
            .with_note("`--generate-macro-expansion` 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 doctest_build_args = matches.opt_strs("doctest-build-arg");

        let unstable_features =
            rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());

        let disable_minification = matches.opt_present("disable-minification");

        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,
            sysroot,
            lint_opts,
            describe_lints,
            lint_cap,
            should_test,
            test_args,
            show_coverage,
            crate_version,
            test_run_directory,
            persist_doctests,
            test_runtool,
            test_runtool_args,
            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,
            doctest_build_args,
            target_modifiers,
        };
        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,
            generate_macro_expansion,
            call_locations,
            no_emit_shared: false,
            html_no_source,
            output_to_stdout,
            should_merge,
            include_parts_dir,
            parts_out_dir,
            disable_minification,
        };
        Some((input, options, render_options, loaded_paths))
    }
}

/// 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`"),
    }
}
