use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::path::{Path, PathBuf};

use log::*;

use crate::common::{self, CompareMode, Config, Mode, PassMode};
use crate::util;
use crate::extract_gdb_version;

#[cfg(test)]
mod tests;

/// Whether to ignore the test.
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum Ignore {
    /// Runs it.
    Run,
    /// Ignore it totally.
    Ignore,
    /// Ignore only the gdb test, but run the lldb test.
    IgnoreGdb,
    /// Ignore only the lldb test, but run the gdb test.
    IgnoreLldb,
}

impl Ignore {
    pub fn can_run_gdb(&self) -> bool {
        *self == Ignore::Run || *self == Ignore::IgnoreLldb
    }

    pub fn can_run_lldb(&self) -> bool {
        *self == Ignore::Run || *self == Ignore::IgnoreGdb
    }

    pub fn no_gdb(&self) -> Ignore {
        match *self {
            Ignore::Run => Ignore::IgnoreGdb,
            Ignore::IgnoreGdb => Ignore::IgnoreGdb,
            _ => Ignore::Ignore,
        }
    }

    pub fn no_lldb(&self) -> Ignore {
        match *self {
            Ignore::Run => Ignore::IgnoreLldb,
            Ignore::IgnoreLldb => Ignore::IgnoreLldb,
            _ => Ignore::Ignore,
        }
    }
}

/// The result of parse_cfg_name_directive.
#[derive(Clone, Copy, PartialEq, Debug)]
enum ParsedNameDirective {
    /// No match.
    NoMatch,
    /// Match.
    Match,
    /// Mode was DebugInfoGdbLldb and this matched gdb.
    MatchGdb,
    /// Mode was DebugInfoGdbLldb and this matched lldb.
    MatchLldb,
}

/// Properties which must be known very early, before actually running
/// the test.
pub struct EarlyProps {
    pub ignore: Ignore,
    pub should_fail: bool,
    pub aux: Vec<String>,
    pub aux_crate: Vec<(String, String)>,
    pub revisions: Vec<String>,
}

impl EarlyProps {
    pub fn from_file(config: &Config, testfile: &Path) -> Self {
        let mut props = EarlyProps {
            ignore: Ignore::Run,
            should_fail: false,
            aux: Vec::new(),
            aux_crate: Vec::new(),
            revisions: vec![],
        };

        if config.mode == common::DebugInfoGdbLldb {
            if config.lldb_python_dir.is_none() {
                props.ignore = props.ignore.no_lldb();
            }
            if config.gdb_version.is_none() {
                props.ignore = props.ignore.no_gdb();
            }
        } else if config.mode == common::DebugInfoCdb {
            if config.cdb.is_none() {
                props.ignore = Ignore::Ignore;
            }
        }

        let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
        let rustc_has_sanitizer_support = env::var_os("RUSTC_SANITIZER_SUPPORT").is_some();

        iter_header(testfile, None, &mut |ln| {
            // we should check if any only-<platform> exists and if it exists
            // and does not matches the current platform, skip the test
            if props.ignore != Ignore::Ignore {
                props.ignore = match config.parse_cfg_name_directive(ln, "ignore") {
                    ParsedNameDirective::Match => Ignore::Ignore,
                    ParsedNameDirective::NoMatch => props.ignore,
                    ParsedNameDirective::MatchGdb => props.ignore.no_gdb(),
                    ParsedNameDirective::MatchLldb => props.ignore.no_lldb(),
                };

                if config.has_cfg_prefix(ln, "only") {
                    props.ignore = match config.parse_cfg_name_directive(ln, "only") {
                        ParsedNameDirective::Match => props.ignore,
                        ParsedNameDirective::NoMatch => Ignore::Ignore,
                        ParsedNameDirective::MatchLldb => props.ignore.no_gdb(),
                        ParsedNameDirective::MatchGdb => props.ignore.no_lldb(),
                    };
                }

                if ignore_llvm(config, ln) {
                    props.ignore = Ignore::Ignore;
                }

                if config.run_clang_based_tests_with.is_none() &&
                   config.parse_needs_matching_clang(ln) {
                    props.ignore = Ignore::Ignore;
                }

                if !rustc_has_profiler_support &&
                   config.parse_needs_profiler_support(ln) {
                    props.ignore = Ignore::Ignore;
                }

                if !rustc_has_sanitizer_support &&
                   config.parse_needs_sanitizer_support(ln) {
                    props.ignore = Ignore::Ignore;
                }

                if config.target == "wasm32-unknown-unknown" && config.parse_check_run_results(ln) {
                    props.ignore = Ignore::Ignore;
                }
            }

            if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoGdbLldb) &&
                props.ignore.can_run_gdb() && ignore_gdb(config, ln) {
                props.ignore = props.ignore.no_gdb();
            }

            if (config.mode == common::DebugInfoLldb || config.mode == common::DebugInfoGdbLldb) &&
                props.ignore.can_run_lldb() && ignore_lldb(config, ln) {
                props.ignore = props.ignore.no_lldb();
            }

            if let Some(s) = config.parse_aux_build(ln) {
                props.aux.push(s);
            }

            if let Some(ac) = config.parse_aux_crate(ln) {
                props.aux_crate.push(ac);
            }

            if let Some(r) = config.parse_revisions(ln) {
                props.revisions.extend(r);
            }

            props.should_fail = props.should_fail || config.parse_name_directive(ln, "should-fail");
        });

        return props;

        fn ignore_gdb(config: &Config, line: &str) -> bool {
            if let Some(actual_version) = config.gdb_version {
                if line.starts_with("min-gdb-version") {
                    let (start_ver, end_ver) = extract_gdb_version_range(line);

                    if start_ver != end_ver {
                        panic!("Expected single GDB version")
                    }
                    // Ignore if actual version is smaller the minimum required
                    // version
                    actual_version < start_ver
                } else if line.starts_with("ignore-gdb-version") {
                    let (min_version, max_version) = extract_gdb_version_range(line);

                    if max_version < min_version {
                        panic!("Malformed GDB version range: max < min")
                    }

                    actual_version >= min_version && actual_version <= max_version
                } else {
                    false
                }
            } else {
                false
            }
        }

        // Takes a directive of the form "ignore-gdb-version <version1> [- <version2>]",
        // returns the numeric representation of <version1> and <version2> as
        // tuple: (<version1> as u32, <version2> as u32)
        // If the <version2> part is omitted, the second component of the tuple
        // is the same as <version1>.
        fn extract_gdb_version_range(line: &str) -> (u32, u32) {
            const ERROR_MESSAGE: &'static str = "Malformed GDB version directive";

            let range_components = line.split(&[' ', '-'][..])
                                       .filter(|word| !word.is_empty())
                                       .map(extract_gdb_version)
                                       .skip_while(Option::is_none)
                                       .take(3) // 3 or more = invalid, so take at most 3.
                                       .collect::<Vec<Option<u32>>>();

            match range_components.len() {
                1 => {
                    let v = range_components[0].unwrap();
                    (v, v)
                }
                2 => {
                    let v_min = range_components[0].unwrap();
                    let v_max = range_components[1].expect(ERROR_MESSAGE);
                    (v_min, v_max)
                }
                _ => panic!(ERROR_MESSAGE),
            }
        }

        fn ignore_lldb(config: &Config, line: &str) -> bool {
            if let Some(ref actual_version) = config.lldb_version {
                if line.starts_with("min-lldb-version") {
                    let min_version = line.trim_end()
                        .rsplit(' ')
                        .next()
                        .expect("Malformed lldb version directive");
                    // Ignore if actual version is smaller the minimum required
                    // version
                    lldb_version_to_int(actual_version) < lldb_version_to_int(min_version)
                } else if line.starts_with("rust-lldb") && !config.lldb_native_rust {
                    true
                } else {
                    false
                }
            } else {
                false
            }
        }

        fn ignore_llvm(config: &Config, line: &str) -> bool {
            if config.system_llvm && line.starts_with("no-system-llvm") {
                return true;
            }
            if let Some(ref actual_version) = config.llvm_version {
                if line.starts_with("min-llvm-version") {
                    let min_version = line.trim_end()
                        .rsplit(' ')
                        .next()
                        .expect("Malformed llvm version directive");
                    // Ignore if actual version is smaller the minimum required
                    // version
                    &actual_version[..] < min_version
                } else if line.starts_with("min-system-llvm-version") {
                    let min_version = line.trim_end()
                        .rsplit(' ')
                        .next()
                        .expect("Malformed llvm version directive");
                    // Ignore if using system LLVM and actual version
                    // is smaller the minimum required version
                    config.system_llvm && &actual_version[..] < min_version
                } else if line.starts_with("ignore-llvm-version") {
                    // Syntax is: "ignore-llvm-version <version1> [- <version2>]"
                    let range_components = line.split(' ')
                        .skip(1) // Skip the directive.
                        .map(|s| s.trim())
                        .filter(|word| !word.is_empty() && word != &"-")
                        .take(3) // 3 or more = invalid, so take at most 3.
                        .collect::<Vec<&str>>();
                    match range_components.len() {
                        1 => {
                            &actual_version[..] == range_components[0]
                        }
                        2 => {
                            let v_min = range_components[0];
                            let v_max = range_components[1];
                            if v_max < v_min {
                                panic!("Malformed LLVM version range: max < min")
                            }
                            // Ignore if version lies inside of range.
                            &actual_version[..] >= v_min && &actual_version[..] <= v_max
                        }
                        _ => panic!("Malformed LLVM version directive"),
                    }
                } else {
                    false
                }
            } else {
                false
            }
        }
    }
}

#[derive(Clone, Debug)]
pub struct TestProps {
    // Lines that should be expected, in order, on standard out
    pub error_patterns: Vec<String>,
    // Extra flags to pass to the compiler
    pub compile_flags: Vec<String>,
    // Extra flags to pass when the compiled code is run (such as --bench)
    pub run_flags: Option<String>,
    // If present, the name of a file that this test should match when
    // pretty-printed
    pub pp_exact: Option<PathBuf>,
    // Other crates that should be compiled (typically from the same
    // directory as the test, but for backwards compatibility reasons
    // we also check the auxiliary directory)
    pub aux_builds: Vec<String>,
    // Similar to `aux_builds`, but a list of NAME=somelib.rs of dependencies
    // to build and pass with the `--extern` flag.
    pub aux_crates: Vec<(String, String)>,
    // Environment settings to use for compiling
    pub rustc_env: Vec<(String, String)>,
    // Environment variables to unset prior to compiling.
    // Variables are unset before applying 'rustc_env'.
    pub unset_rustc_env: Vec<String>,
    // Environment settings to use during execution
    pub exec_env: Vec<(String, String)>,
    // Lines to check if they appear in the expected debugger output
    pub check_lines: Vec<String>,
    // Build documentation for all specified aux-builds as well
    pub build_aux_docs: bool,
    // Flag to force a crate to be built with the host architecture
    pub force_host: bool,
    // Check stdout for error-pattern output as well as stderr
    pub check_stdout: bool,
    // Check stdout & stderr for output of run-pass test
    pub check_run_results: bool,
    // For UI tests, allows compiler to generate arbitrary output to stdout
    pub dont_check_compiler_stdout: bool,
    // For UI tests, allows compiler to generate arbitrary output to stderr
    pub dont_check_compiler_stderr: bool,
    // Don't force a --crate-type=dylib flag on the command line
    //
    // Set this for example if you have an auxiliary test file that contains
    // a proc-macro and needs `#![crate_type = "proc-macro"]`. This ensures
    // that the aux file is compiled as a `proc-macro` and not as a `dylib`.
    pub no_prefer_dynamic: bool,
    // Run --pretty expanded when running pretty printing tests
    pub pretty_expanded: bool,
    // Which pretty mode are we testing with, default to 'normal'
    pub pretty_mode: String,
    // Only compare pretty output and don't try compiling
    pub pretty_compare_only: bool,
    // Patterns which must not appear in the output of a cfail test.
    pub forbid_output: Vec<String>,
    // Revisions to test for incremental compilation.
    pub revisions: Vec<String>,
    // Directory (if any) to use for incremental compilation.  This is
    // not set by end-users; rather it is set by the incremental
    // testing harness and used when generating compilation
    // arguments. (In particular, it propagates to the aux-builds.)
    pub incremental_dir: Option<PathBuf>,
    // How far should the test proceed while still passing.
    pass_mode: Option<PassMode>,
    // Ignore `--pass` overrides from the command line for this test.
    ignore_pass: bool,
    // rustdoc will test the output of the `--test` option
    pub check_test_line_numbers_match: bool,
    // Do not pass `-Z ui-testing` to UI tests
    pub disable_ui_testing_normalization: bool,
    // customized normalization rules
    pub normalize_stdout: Vec<(String, String)>,
    pub normalize_stderr: Vec<(String, String)>,
    pub failure_status: i32,
    // Whether or not `rustfix` should apply the `CodeSuggestion`s of this test and compile the
    // resulting Rust code.
    pub run_rustfix: bool,
    // If true, `rustfix` will only apply `MachineApplicable` suggestions.
    pub rustfix_only_machine_applicable: bool,
    pub assembly_output: Option<String>,
    // If true, the test is expected to ICE
    pub should_ice: bool,
}

impl TestProps {
    pub fn new() -> Self {
        TestProps {
            error_patterns: vec![],
            compile_flags: vec![],
            run_flags: None,
            pp_exact: None,
            aux_builds: vec![],
            aux_crates: vec![],
            revisions: vec![],
            rustc_env: vec![],
            unset_rustc_env: vec![],
            exec_env: vec![],
            check_lines: vec![],
            build_aux_docs: false,
            force_host: false,
            check_stdout: false,
            check_run_results: false,
            dont_check_compiler_stdout: false,
            dont_check_compiler_stderr: false,
            no_prefer_dynamic: false,
            pretty_expanded: false,
            pretty_mode: "normal".to_string(),
            pretty_compare_only: false,
            forbid_output: vec![],
            incremental_dir: None,
            pass_mode: None,
            ignore_pass: false,
            check_test_line_numbers_match: false,
            disable_ui_testing_normalization: false,
            normalize_stdout: vec![],
            normalize_stderr: vec![],
            failure_status: -1,
            run_rustfix: false,
            rustfix_only_machine_applicable: false,
            assembly_output: None,
            should_ice: false,
        }
    }

    pub fn from_aux_file(&self, testfile: &Path, cfg: Option<&str>, config: &Config) -> Self {
        let mut props = TestProps::new();

        // copy over select properties to the aux build:
        props.incremental_dir = self.incremental_dir.clone();
        props.load_from(testfile, cfg, config);

        props
    }

    pub fn from_file(testfile: &Path, cfg: Option<&str>, config: &Config) -> Self {
        let mut props = TestProps::new();
        props.load_from(testfile, cfg, config);
        props
    }

    /// Loads properties from `testfile` into `props`. If a property is
    /// tied to a particular revision `foo` (indicated by writing
    /// `//[foo]`), then the property is ignored unless `cfg` is
    /// `Some("foo")`.
    fn load_from(&mut self, testfile: &Path, cfg: Option<&str>, config: &Config) {
        iter_header(testfile, cfg, &mut |ln| {
            if let Some(ep) = config.parse_error_pattern(ln) {
                self.error_patterns.push(ep);
            }

            if let Some(flags) = config.parse_compile_flags(ln) {
                self.compile_flags
                    .extend(flags.split_whitespace().map(|s| s.to_owned()));
            }

            if let Some(edition) = config.parse_edition(ln) {
                self.compile_flags.push(format!("--edition={}", edition));
            }

            if let Some(r) = config.parse_revisions(ln) {
                self.revisions.extend(r);
            }

            if self.run_flags.is_none() {
                self.run_flags = config.parse_run_flags(ln);
            }

            if self.pp_exact.is_none() {
                self.pp_exact = config.parse_pp_exact(ln, testfile);
            }

            if !self.should_ice {
                self.should_ice = config.parse_should_ice(ln);
            }

            if !self.build_aux_docs {
                self.build_aux_docs = config.parse_build_aux_docs(ln);
            }

            if !self.force_host {
                self.force_host = config.parse_force_host(ln);
            }

            if !self.check_stdout {
                self.check_stdout = config.parse_check_stdout(ln);
            }

            if !self.check_run_results {
                self.check_run_results = config.parse_check_run_results(ln);
            }

            if !self.dont_check_compiler_stdout {
                self.dont_check_compiler_stdout = config.parse_dont_check_compiler_stdout(ln);
            }

            if !self.dont_check_compiler_stderr {
                self.dont_check_compiler_stderr = config.parse_dont_check_compiler_stderr(ln);
            }

            if !self.no_prefer_dynamic {
                self.no_prefer_dynamic = config.parse_no_prefer_dynamic(ln);
            }

            if !self.pretty_expanded {
                self.pretty_expanded = config.parse_pretty_expanded(ln);
            }

            if let Some(m) = config.parse_pretty_mode(ln) {
                self.pretty_mode = m;
            }

            if !self.pretty_compare_only {
                self.pretty_compare_only = config.parse_pretty_compare_only(ln);
            }

            if let Some(ab) = config.parse_aux_build(ln) {
                self.aux_builds.push(ab);
            }

            if let Some(ac) = config.parse_aux_crate(ln) {
                self.aux_crates.push(ac);
            }

            if let Some(ee) = config.parse_env(ln, "exec-env") {
                self.exec_env.push(ee);
            }

            if let Some(ee) = config.parse_env(ln, "rustc-env") {
                self.rustc_env.push(ee);
            }

            if let Some(ev) = config.parse_name_value_directive(ln, "unset-rustc-env") {
                self.unset_rustc_env.push(ev);
            }

            if let Some(cl) = config.parse_check_line(ln) {
                self.check_lines.push(cl);
            }

            if let Some(of) = config.parse_forbid_output(ln) {
                self.forbid_output.push(of);
            }

            if !self.check_test_line_numbers_match {
                self.check_test_line_numbers_match = config.parse_check_test_line_numbers_match(ln);
            }

            self.update_pass_mode(ln, cfg, config);

            if !self.ignore_pass {
                self.ignore_pass = config.parse_ignore_pass(ln);
            }

            if !self.disable_ui_testing_normalization {
                self.disable_ui_testing_normalization =
                    config.parse_disable_ui_testing_normalization(ln);
            }

            if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stdout") {
                self.normalize_stdout.push(rule);
            }
            if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stderr") {
                self.normalize_stderr.push(rule);
            }

            if let Some(code) = config.parse_failure_status(ln) {
                self.failure_status = code;
            }

            if !self.run_rustfix {
                self.run_rustfix = config.parse_run_rustfix(ln);
            }

            if !self.rustfix_only_machine_applicable {
                self.rustfix_only_machine_applicable =
                    config.parse_rustfix_only_machine_applicable(ln);
            }

            if self.assembly_output.is_none() {
                self.assembly_output = config.parse_assembly_output(ln);
            }
        });

        if self.failure_status == -1 {
            self.failure_status = match config.mode {
                Mode::RunFail => 101,
                _ => 1,
            };
        }
        if self.should_ice {
            self.failure_status = 101;
        }

        for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
            if let Ok(val) = env::var(key) {
                if self.exec_env.iter().find(|&&(ref x, _)| x == key).is_none() {
                    self.exec_env.push(((*key).to_owned(), val))
                }
            }
        }
    }

    fn update_pass_mode(&mut self, ln: &str, revision: Option<&str>, config: &Config) {
        let check_no_run = |s| {
            if config.mode != Mode::Ui && config.mode != Mode::Incremental {
                panic!("`{}` header is only supported in UI and incremental tests", s);
            }
            if config.mode == Mode::Incremental &&
                !revision.map_or(false, |r| r.starts_with("cfail")) &&
                !self.revisions.iter().all(|r| r.starts_with("cfail")) {
                panic!("`{}` header is only supported in `cfail` incremental tests", s);
            }
        };
        let pass_mode = if config.parse_name_directive(ln, "check-pass") {
            check_no_run("check-pass");
            Some(PassMode::Check)
        } else if config.parse_name_directive(ln, "build-pass") {
            check_no_run("build-pass");
            Some(PassMode::Build)
        } else if config.parse_name_directive(ln, "run-pass") {
            if config.mode != Mode::Ui {
                panic!("`run-pass` header is only supported in UI tests")
            }
            Some(PassMode::Run)
        } else if config.parse_name_directive(ln, "run-fail") {
            if config.mode != Mode::Ui {
                panic!("`run-fail` header is only supported in UI tests")
            }
            Some(PassMode::RunFail)
        } else {
            None
        };
        match (self.pass_mode, pass_mode) {
            (None, Some(_)) => self.pass_mode = pass_mode,
            (Some(_), Some(_)) => panic!("multiple `*-pass` headers in a single test"),
            (_, None) => {}
        }
    }

    pub fn pass_mode(&self, config: &Config) -> Option<PassMode> {
        if !self.ignore_pass {
            if let (mode @ Some(_), Some(_)) = (config.force_pass_mode, self.pass_mode) {
                return mode;
            }
        }
        self.pass_mode
    }

    // does not consider CLI override for pass mode
    pub fn local_pass_mode(&self) -> Option<PassMode> {
        self.pass_mode
    }
}

fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
    if testfile.is_dir() {
        return;
    }

    let comment = if testfile.to_string_lossy().ends_with(".rs") {
        "//"
    } else {
        "#"
    };

    // FIXME: would be nice to allow some whitespace between comment and brace :)
    // It took me like 2 days to debug why compile-flags weren’t taken into account for my test :)
    let comment_with_brace = comment.to_string() + "[";

    let rdr = BufReader::new(File::open(testfile).unwrap());
    for ln in rdr.lines() {
        // Assume that any directives will be found before the first
        // module or function. This doesn't seem to be an optimization
        // with a warm page cache. Maybe with a cold one.
        let ln = ln.unwrap();
        let ln = ln.trim();
        if ln.starts_with("fn") || ln.starts_with("mod") {
            return;
        } else if ln.starts_with(&comment_with_brace) {
            // A comment like `//[foo]` is specific to revision `foo`
            if let Some(close_brace) = ln.find(']') {
                let open_brace = ln.find('[').unwrap();
                let lncfg = &ln[open_brace + 1 .. close_brace];
                let matches = match cfg {
                    Some(s) => s == &lncfg[..],
                    None => false,
                };
                if matches {
                    it(ln[(close_brace + 1)..].trim_start());
                }
            } else {
                panic!("malformed condition directive: expected `{}foo]`, found `{}`",
                        comment_with_brace, ln)
            }
        } else if ln.starts_with(comment) {
            it(ln[comment.len() ..].trim_start());
        }
    }
    return;
}

impl Config {
    fn parse_should_ice(&self, line: &str) -> bool {
        self.parse_name_directive(line, "should-ice")
    }
    fn parse_error_pattern(&self, line: &str) -> Option<String> {
        self.parse_name_value_directive(line, "error-pattern")
    }

    fn parse_forbid_output(&self, line: &str) -> Option<String> {
        self.parse_name_value_directive(line, "forbid-output")
    }

    fn parse_aux_build(&self, line: &str) -> Option<String> {
        self.parse_name_value_directive(line, "aux-build")
            .map(|r| r.trim().to_string())
    }

    fn parse_aux_crate(&self, line: &str) -> Option<(String, String)> {
        self.parse_name_value_directive(line, "aux-crate").map(|r| {
            let mut parts = r.trim().splitn(2, '=');
            (
                parts.next().expect("aux-crate name").to_string(),
                parts.next().expect("aux-crate value").to_string(),
            )
        })
    }

    fn parse_compile_flags(&self, line: &str) -> Option<String> {
        self.parse_name_value_directive(line, "compile-flags")
    }

    fn parse_revisions(&self, line: &str) -> Option<Vec<String>> {
        self.parse_name_value_directive(line, "revisions")
            .map(|r| r.split_whitespace().map(|t| t.to_string()).collect())
    }

    fn parse_run_flags(&self, line: &str) -> Option<String> {
        self.parse_name_value_directive(line, "run-flags")
    }

    fn parse_check_line(&self, line: &str) -> Option<String> {
        self.parse_name_value_directive(line, "check")
    }

    fn parse_force_host(&self, line: &str) -> bool {
        self.parse_name_directive(line, "force-host")
    }

    fn parse_build_aux_docs(&self, line: &str) -> bool {
        self.parse_name_directive(line, "build-aux-docs")
    }

    fn parse_check_stdout(&self, line: &str) -> bool {
        self.parse_name_directive(line, "check-stdout")
    }

    fn parse_check_run_results(&self, line: &str) -> bool {
        self.parse_name_directive(line, "check-run-results")
    }

    fn parse_dont_check_compiler_stdout(&self, line: &str) -> bool {
        self.parse_name_directive(line, "dont-check-compiler-stdout")
    }

    fn parse_dont_check_compiler_stderr(&self, line: &str) -> bool {
        self.parse_name_directive(line, "dont-check-compiler-stderr")
    }

    fn parse_no_prefer_dynamic(&self, line: &str) -> bool {
        self.parse_name_directive(line, "no-prefer-dynamic")
    }

    fn parse_pretty_expanded(&self, line: &str) -> bool {
        self.parse_name_directive(line, "pretty-expanded")
    }

    fn parse_pretty_mode(&self, line: &str) -> Option<String> {
        self.parse_name_value_directive(line, "pretty-mode")
    }

    fn parse_pretty_compare_only(&self, line: &str) -> bool {
        self.parse_name_directive(line, "pretty-compare-only")
    }

    fn parse_failure_status(&self, line: &str) -> Option<i32> {
        match self.parse_name_value_directive(line, "failure-status") {
            Some(code) => code.trim().parse::<i32>().ok(),
            _ => None,
        }
    }

    fn parse_disable_ui_testing_normalization(&self, line: &str) -> bool {
        self.parse_name_directive(line, "disable-ui-testing-normalization")
    }

    fn parse_check_test_line_numbers_match(&self, line: &str) -> bool {
        self.parse_name_directive(line, "check-test-line-numbers-match")
    }

    fn parse_ignore_pass(&self, line: &str) -> bool {
        self.parse_name_directive(line, "ignore-pass")
    }

    fn parse_assembly_output(&self, line: &str) -> Option<String> {
        self.parse_name_value_directive(line, "assembly-output")
            .map(|r| r.trim().to_string())
    }

    fn parse_env(&self, line: &str, name: &str) -> Option<(String, String)> {
        self.parse_name_value_directive(line, name).map(|nv| {
            // nv is either FOO or FOO=BAR
            let mut strs: Vec<String> = nv.splitn(2, '=').map(str::to_owned).collect();

            match strs.len() {
                1 => (strs.pop().unwrap(), String::new()),
                2 => {
                    let end = strs.pop().unwrap();
                    (strs.pop().unwrap(), end)
                }
                n => panic!("Expected 1 or 2 strings, not {}", n),
            }
        })
    }

    fn parse_pp_exact(&self, line: &str, testfile: &Path) -> Option<PathBuf> {
        if let Some(s) = self.parse_name_value_directive(line, "pp-exact") {
            Some(PathBuf::from(&s))
        } else if self.parse_name_directive(line, "pp-exact") {
            testfile.file_name().map(PathBuf::from)
        } else {
            None
        }
    }

    fn parse_custom_normalization(&self, mut line: &str, prefix: &str) -> Option<(String, String)> {
        if self.parse_cfg_name_directive(line, prefix) == ParsedNameDirective::Match {
            let from = parse_normalization_string(&mut line)?;
            let to = parse_normalization_string(&mut line)?;
            Some((from, to))
        } else {
            None
        }
    }

    fn parse_needs_matching_clang(&self, line: &str) -> bool {
        self.parse_name_directive(line, "needs-matching-clang")
    }

    fn parse_needs_profiler_support(&self, line: &str) -> bool {
        self.parse_name_directive(line, "needs-profiler-support")
    }

    fn parse_needs_sanitizer_support(&self, line: &str) -> bool {
        self.parse_name_directive(line, "needs-sanitizer-support")
    }

    /// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86`
    /// or `normalize-stderr-32bit`.
    fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective {
        if line.starts_with(prefix) && line.as_bytes().get(prefix.len()) == Some(&b'-') {
            let name = line[prefix.len() + 1..]
                .split(&[':', ' '][..])
                .next()
                .unwrap();

            if name == "test" ||
                util::matches_os(&self.target, name) ||             // target
                util::matches_env(&self.target, name) ||            // env
                name == util::get_arch(&self.target) ||             // architecture
                name == util::get_pointer_width(&self.target) ||    // pointer width
                name == self.stage_id.split('-').next().unwrap() || // stage
                (self.target != self.host && name == "cross-compile") ||
                match self.compare_mode {
                    Some(CompareMode::Nll) => name == "compare-mode-nll",
                    Some(CompareMode::Polonius) => name == "compare-mode-polonius",
                    None => false,
                } ||
                (cfg!(debug_assertions) && name == "debug") {
                ParsedNameDirective::Match
            } else {
                match self.mode {
                    common::DebugInfoGdbLldb => {
                        if name == "gdb" {
                            ParsedNameDirective::MatchGdb
                        } else if name == "lldb" {
                            ParsedNameDirective::MatchLldb
                        } else {
                            ParsedNameDirective::NoMatch
                        }
                    },
                    common::DebugInfoCdb => if name == "cdb" {
                        ParsedNameDirective::Match
                    } else {
                        ParsedNameDirective::NoMatch
                    },
                    common::DebugInfoGdb => if name == "gdb" {
                        ParsedNameDirective::Match
                    } else {
                        ParsedNameDirective::NoMatch
                    },
                    common::DebugInfoLldb => if name == "lldb" {
                        ParsedNameDirective::Match
                    } else {
                        ParsedNameDirective::NoMatch
                    },
                    common::Pretty => if name == "pretty" {
                        ParsedNameDirective::Match
                    } else {
                        ParsedNameDirective::NoMatch
                    },
                    _ => ParsedNameDirective::NoMatch,
                }
            }
        } else {
            ParsedNameDirective::NoMatch
        }
    }

    fn has_cfg_prefix(&self, line: &str, prefix: &str) -> bool {
        // returns whether this line contains this prefix or not. For prefix
        // "ignore", returns true if line says "ignore-x86_64", "ignore-arch",
        // "ignore-android" etc.
        line.starts_with(prefix) && line.as_bytes().get(prefix.len()) == Some(&b'-')
    }

    fn parse_name_directive(&self, line: &str, directive: &str) -> bool {
        // Ensure the directive is a whole word. Do not match "ignore-x86" when
        // the line says "ignore-x86_64".
        line.starts_with(directive) && match line.as_bytes().get(directive.len()) {
            None | Some(&b' ') | Some(&b':') => true,
            _ => false,
        }
    }

    pub fn parse_name_value_directive(&self, line: &str, directive: &str) -> Option<String> {
        let colon = directive.len();
        if line.starts_with(directive) && line.as_bytes().get(colon) == Some(&b':') {
            let value = line[(colon + 1)..].to_owned();
            debug!("{}: {}", directive, value);
            Some(expand_variables(value, self))
        } else {
            None
        }
    }

    pub fn find_rust_src_root(&self) -> Option<PathBuf> {
        let mut path = self.src_base.clone();
        let path_postfix = Path::new("src/etc/lldb_batchmode.py");

        while path.pop() {
            if path.join(&path_postfix).is_file() {
                return Some(path);
            }
        }

        None
    }

    fn parse_run_rustfix(&self, line: &str) -> bool {
        self.parse_name_directive(line, "run-rustfix")
    }

    fn parse_rustfix_only_machine_applicable(&self, line: &str) -> bool {
        self.parse_name_directive(line, "rustfix-only-machine-applicable")
    }

    fn parse_edition(&self, line: &str) -> Option<String> {
        self.parse_name_value_directive(line, "edition")
    }
}

pub fn lldb_version_to_int(version_string: &str) -> isize {
    let error_string = format!(
        "Encountered LLDB version string with unexpected format: {}",
        version_string
    );
    version_string.parse().expect(&error_string)
}

fn expand_variables(mut value: String, config: &Config) -> String {
    const CWD: &'static str = "{{cwd}}";
    const SRC_BASE: &'static str = "{{src-base}}";
    const BUILD_BASE: &'static str = "{{build-base}}";

    if value.contains(CWD) {
        let cwd = env::current_dir().unwrap();
        value = value.replace(CWD, &cwd.to_string_lossy());
    }

    if value.contains(SRC_BASE) {
        value = value.replace(SRC_BASE, &config.src_base.to_string_lossy());
    }

    if value.contains(BUILD_BASE) {
        value = value.replace(BUILD_BASE, &config.build_base.to_string_lossy());
    }

    value
}

/// Finds the next quoted string `"..."` in `line`, and extract the content from it. Move the `line`
/// variable after the end of the quoted string.
///
/// # Examples
///
/// ```
/// let mut s = "normalize-stderr-32bit: \"something (32 bits)\" -> \"something ($WORD bits)\".";
/// let first = parse_normalization_string(&mut s);
/// assert_eq!(first, Some("something (32 bits)".to_owned()));
/// assert_eq!(s, " -> \"something ($WORD bits)\".");
/// ```
fn parse_normalization_string(line: &mut &str) -> Option<String> {
    // FIXME support escapes in strings.
    let begin = line.find('"')? + 1;
    let end = line[begin..].find('"')? + begin;
    let result = line[begin..end].to_owned();
    *line = &line[end + 1..];
    Some(result)
}
