use super::*;

fn init_source_map() -> SourceMap {
    let sm = SourceMap::new(FilePathMapping::empty());
    sm.new_source_file(PathBuf::from("blork.rs").into(), "first line.\nsecond line".to_string());
    sm.new_source_file(PathBuf::from("empty.rs").into(), String::new());
    sm.new_source_file(PathBuf::from("blork2.rs").into(), "first line.\nsecond line".to_string());
    sm
}

impl SourceMap {
    /// Returns `Some(span)`, a union of the LHS and RHS span. The LHS must precede the RHS. If
    /// there are gaps between LHS and RHS, the resulting union will cross these gaps.
    /// For this to work,
    ///
    ///    * the syntax contexts of both spans much match,
    ///    * the LHS span needs to end on the same line the RHS span begins,
    ///    * the LHS span must start at or before the RHS span.
    fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option<Span> {
        // Ensure we're at the same expansion ID.
        if !sp_lhs.eq_ctxt(sp_rhs) {
            return None;
        }

        let lhs_end = match self.lookup_line(sp_lhs.hi()) {
            Ok(x) => x,
            Err(_) => return None,
        };
        let rhs_begin = match self.lookup_line(sp_rhs.lo()) {
            Ok(x) => x,
            Err(_) => return None,
        };

        // If we must cross lines to merge, don't merge.
        if lhs_end.line != rhs_begin.line {
            return None;
        }

        // Ensure these follow the expected order and that we don't overlap.
        if (sp_lhs.lo() <= sp_rhs.lo()) && (sp_lhs.hi() <= sp_rhs.lo()) {
            Some(sp_lhs.to(sp_rhs))
        } else {
            None
        }
    }

    /// Converts an absolute `BytePos` to a `CharPos` relative to the `SourceFile`.
    fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
        let idx = self.lookup_source_file_idx(bpos);
        let sf = &(*self.files.borrow().source_files)[idx];
        let bpos = sf.relative_position(bpos);
        sf.bytepos_to_file_charpos(bpos)
    }
}

/// Tests `lookup_byte_offset`.
#[test]
fn t3() {
    let sm = init_source_map();

    let srcfbp1 = sm.lookup_byte_offset(BytePos(23));
    assert_eq!(srcfbp1.sf.name, PathBuf::from("blork.rs").into());
    assert_eq!(srcfbp1.pos, BytePos(23));

    let srcfbp1 = sm.lookup_byte_offset(BytePos(24));
    assert_eq!(srcfbp1.sf.name, PathBuf::from("empty.rs").into());
    assert_eq!(srcfbp1.pos, BytePos(0));

    let srcfbp2 = sm.lookup_byte_offset(BytePos(25));
    assert_eq!(srcfbp2.sf.name, PathBuf::from("blork2.rs").into());
    assert_eq!(srcfbp2.pos, BytePos(0));
}

/// Tests `bytepos_to_file_charpos`.
#[test]
fn t4() {
    let sm = init_source_map();

    let cp1 = sm.bytepos_to_file_charpos(BytePos(22));
    assert_eq!(cp1, CharPos(22));

    let cp2 = sm.bytepos_to_file_charpos(BytePos(25));
    assert_eq!(cp2, CharPos(0));
}

/// Tests zero-length `SourceFile`s.
#[test]
fn t5() {
    let sm = init_source_map();

    let loc1 = sm.lookup_char_pos(BytePos(22));
    assert_eq!(loc1.file.name, PathBuf::from("blork.rs").into());
    assert_eq!(loc1.line, 2);
    assert_eq!(loc1.col, CharPos(10));

    let loc2 = sm.lookup_char_pos(BytePos(25));
    assert_eq!(loc2.file.name, PathBuf::from("blork2.rs").into());
    assert_eq!(loc2.line, 1);
    assert_eq!(loc2.col, CharPos(0));
}

fn init_source_map_mbc() -> SourceMap {
    let sm = SourceMap::new(FilePathMapping::empty());
    // "€" is a three-byte UTF8 char.
    sm.new_source_file(
        PathBuf::from("blork.rs").into(),
        "fir€st €€€€ line.\nsecond line".to_string(),
    );
    sm.new_source_file(
        PathBuf::from("blork2.rs").into(),
        "first line€€.\n€ second line".to_string(),
    );
    sm
}

/// Tests `bytepos_to_file_charpos` in the presence of multi-byte chars.
#[test]
fn t6() {
    let sm = init_source_map_mbc();

    let cp1 = sm.bytepos_to_file_charpos(BytePos(3));
    assert_eq!(cp1, CharPos(3));

    let cp2 = sm.bytepos_to_file_charpos(BytePos(6));
    assert_eq!(cp2, CharPos(4));

    let cp3 = sm.bytepos_to_file_charpos(BytePos(56));
    assert_eq!(cp3, CharPos(12));

    let cp4 = sm.bytepos_to_file_charpos(BytePos(61));
    assert_eq!(cp4, CharPos(15));
}

/// Test `span_to_lines` for a span ending at the end of a `SourceFile`.
#[test]
fn t7() {
    let sm = init_source_map();
    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
    let file_lines = sm.span_to_lines(span).unwrap();

    assert_eq!(file_lines.file.name, PathBuf::from("blork.rs").into());
    assert_eq!(file_lines.lines.len(), 1);
    assert_eq!(file_lines.lines[0].line_index, 1);
}

/// Given a string like " ~~~~~~~~~~~~ ", produces a span
/// converting that range. The idea is that the string has the same
/// length as the input, and we uncover the byte positions. Note
/// that this can span lines and so on.
fn span_from_selection(input: &str, selection: &str) -> Span {
    assert_eq!(input.len(), selection.len());
    let left_index = selection.find('~').unwrap() as u32;
    let right_index = selection.rfind('~').map_or(left_index, |x| x as u32);
    Span::with_root_ctxt(BytePos(left_index), BytePos(right_index + 1))
}

/// Tests `span_to_snippet` and `span_to_lines` for a span converting 3
/// lines in the middle of a file.
#[test]
fn span_to_snippet_and_lines_spanning_multiple_lines() {
    let sm = SourceMap::new(FilePathMapping::empty());
    let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n";
    let selection = "     \n    ~~\n~~~\n~~~~~     \n   \n";
    sm.new_source_file(Path::new("blork.rs").to_owned().into(), inputtext.to_string());
    let span = span_from_selection(inputtext, selection);

    // Check that we are extracting the text we thought we were extracting.
    assert_eq!(&sm.span_to_snippet(span).unwrap(), "BB\nCCC\nDDDDD");

    // Check that span_to_lines gives us the complete result with the lines/cols we expected.
    let lines = sm.span_to_lines(span).unwrap();
    let expected = vec![
        LineInfo { line_index: 1, start_col: CharPos(4), end_col: CharPos(6) },
        LineInfo { line_index: 2, start_col: CharPos(0), end_col: CharPos(3) },
        LineInfo { line_index: 3, start_col: CharPos(0), end_col: CharPos(5) },
    ];
    assert_eq!(lines.lines, expected);
}

/// Test span_to_snippet for a span ending at the end of a `SourceFile`.
#[test]
fn t8() {
    let sm = init_source_map();
    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
    let snippet = sm.span_to_snippet(span);

    assert_eq!(snippet, Ok("second line".to_string()));
}

/// Test `span_to_str` for a span ending at the end of a `SourceFile`.
#[test]
fn t9() {
    let sm = init_source_map();
    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
    let sstr = sm.span_to_diagnostic_string(span);

    assert_eq!(sstr, "blork.rs:2:1: 2:12");
}

/// Tests failing to merge two spans on different lines.
#[test]
fn span_merging_fail() {
    let sm = SourceMap::new(FilePathMapping::empty());
    let inputtext = "bbbb BB\ncc CCC\n";
    let selection1 = "     ~~\n      \n";
    let selection2 = "       \n   ~~~\n";
    sm.new_source_file(Path::new("blork.rs").to_owned().into(), inputtext.to_owned());
    let span1 = span_from_selection(inputtext, selection1);
    let span2 = span_from_selection(inputtext, selection2);

    assert!(sm.merge_spans(span1, span2).is_none());
}

/// Tests loading an external source file that requires normalization.
#[test]
fn t10() {
    let sm = SourceMap::new(FilePathMapping::empty());
    let unnormalized = "first line.\r\nsecond line";
    let normalized = "first line.\nsecond line";

    let src_file = sm.new_source_file(PathBuf::from("blork.rs").into(), unnormalized.to_string());

    assert_eq!(src_file.src.as_ref().unwrap().as_ref(), normalized);
    assert!(
        src_file.src_hash.matches(unnormalized),
        "src_hash should use the source before normalization"
    );

    let SourceFile {
        name,
        src_hash,
        checksum_hash,
        normalized_source_len,
        unnormalized_source_len,
        lines,
        multibyte_chars,
        normalized_pos,
        stable_id,
        ..
    } = (*src_file).clone();

    let imported_src_file = sm.new_imported_source_file(
        name,
        src_hash,
        checksum_hash,
        stable_id,
        normalized_source_len.to_u32(),
        unnormalized_source_len,
        CrateNum::ZERO,
        FreezeLock::new(lines.read().clone()),
        multibyte_chars,
        normalized_pos,
        0,
    );

    assert!(
        imported_src_file.external_src.borrow().get_source().is_none(),
        "imported source file should not have source yet"
    );
    imported_src_file.add_external_src(|| Some(unnormalized.to_string()));
    assert_eq!(
        imported_src_file.external_src.borrow().get_source().unwrap(),
        normalized,
        "imported source file should be normalized"
    );
}

// Takes a unix-style path and returns a platform specific path.
fn path(p: &str) -> PathBuf {
    path_str(p).into()
}

// Takes a unix-style path and returns a platform specific path.
fn path_str(p: &str) -> String {
    #[cfg(not(windows))]
    {
        return p.into();
    }

    #[cfg(windows)]
    {
        let mut path = p.replace('/', "\\");
        if let Some(rest) = path.strip_prefix('\\') {
            path = ["X:\\", rest].concat();
        }

        path
    }
}

fn map_path_prefix(mapping: &FilePathMapping, p: &str) -> String {
    // It's important that we convert to a string here because that's what
    // later stages do too (e.g. in the backend), and comparing `Path` values
    // won't catch some differences at the string level, e.g. "abc" and "abc/"
    // compare as equal.
    mapping.map_prefix(path(p)).0.to_string_lossy().to_string()
}

fn reverse_map_prefix(mapping: &FilePathMapping, p: &str) -> Option<String> {
    mapping.reverse_map_prefix_heuristically(&path(p)).map(|q| q.to_string_lossy().to_string())
}

#[test]
fn path_prefix_remapping() {
    // Relative to relative
    {
        let mapping = &FilePathMapping::new(
            vec![(path("abc/def"), path("foo"))],
            FileNameDisplayPreference::Remapped,
            FileNameEmbeddablePreference::RemappedOnly,
        );

        assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("foo/src/main.rs"));
        assert_eq!(map_path_prefix(mapping, "abc/def"), path_str("foo"));
    }

    // Relative to absolute
    {
        let mapping = &FilePathMapping::new(
            vec![(path("abc/def"), path("/foo"))],
            FileNameDisplayPreference::Remapped,
            FileNameEmbeddablePreference::RemappedOnly,
        );

        assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("/foo/src/main.rs"));
        assert_eq!(map_path_prefix(mapping, "abc/def"), path_str("/foo"));
    }

    // Absolute to relative
    {
        let mapping = &FilePathMapping::new(
            vec![(path("/abc/def"), path("foo"))],
            FileNameDisplayPreference::Remapped,
            FileNameEmbeddablePreference::RemappedOnly,
        );

        assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("foo/src/main.rs"));
        assert_eq!(map_path_prefix(mapping, "/abc/def"), path_str("foo"));
    }

    // Absolute to absolute
    {
        let mapping = &FilePathMapping::new(
            vec![(path("/abc/def"), path("/foo"))],
            FileNameDisplayPreference::Remapped,
            FileNameEmbeddablePreference::RemappedOnly,
        );

        assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("/foo/src/main.rs"));
        assert_eq!(map_path_prefix(mapping, "/abc/def"), path_str("/foo"));
    }
}

#[test]
fn path_prefix_remapping_expand_to_absolute() {
    // "virtual" working directory is relative path
    let mapping = &FilePathMapping::new(
        vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))],
        FileNameDisplayPreference::Remapped,
        FileNameEmbeddablePreference::RemappedOnly,
    );
    let working_directory = path("/foo");
    let working_directory = RealFileName::Remapped {
        local_path: Some(working_directory.clone()),
        virtual_name: mapping.map_prefix(working_directory).0.into_owned(),
    };

    assert_eq!(working_directory.remapped_path_if_available(), path("FOO"));

    // Unmapped absolute path
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::LocalPath(path("/foo/src/main.rs")),
            &working_directory
        ),
        RealFileName::Remapped { local_path: None, virtual_name: path("FOO/src/main.rs") }
    );

    // Unmapped absolute path with unrelated working directory
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::LocalPath(path("/bar/src/main.rs")),
            &working_directory
        ),
        RealFileName::Remapped { local_path: None, virtual_name: path("BAR/src/main.rs") }
    );

    // Unmapped absolute path that does not match any prefix
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::LocalPath(path("/quux/src/main.rs")),
            &working_directory
        ),
        RealFileName::LocalPath(path("/quux/src/main.rs")),
    );

    // Unmapped relative path
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::LocalPath(path("src/main.rs")),
            &working_directory
        ),
        RealFileName::Remapped { local_path: None, virtual_name: path("FOO/src/main.rs") }
    );

    // Unmapped relative path with `./`
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::LocalPath(path("./src/main.rs")),
            &working_directory
        ),
        RealFileName::Remapped { local_path: None, virtual_name: path("FOO/src/main.rs") }
    );

    // Unmapped relative path that does not match any prefix
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::LocalPath(path("quux/src/main.rs")),
            &RealFileName::LocalPath(path("/abc")),
        ),
        RealFileName::LocalPath(path("/abc/quux/src/main.rs")),
    );

    // Already remapped absolute path
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::Remapped {
                local_path: Some(path("/foo/src/main.rs")),
                virtual_name: path("FOO/src/main.rs"),
            },
            &working_directory
        ),
        RealFileName::Remapped { local_path: None, virtual_name: path("FOO/src/main.rs") }
    );

    // Already remapped absolute path, with unrelated working directory
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::Remapped {
                local_path: Some(path("/bar/src/main.rs")),
                virtual_name: path("BAR/src/main.rs"),
            },
            &working_directory
        ),
        RealFileName::Remapped { local_path: None, virtual_name: path("BAR/src/main.rs") }
    );

    // Already remapped relative path
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") },
            &working_directory
        ),
        RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") }
    );
}

#[test]
fn path_prefix_remapping_expand_to_absolute_and_local() {
    // "virtual" working directory is relative path
    let mapping = &FilePathMapping::new(
        vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))],
        FileNameDisplayPreference::Remapped,
        FileNameEmbeddablePreference::LocalAndRemapped,
    );
    let working_directory = path("/foo");
    let working_directory = RealFileName::Remapped {
        local_path: Some(working_directory.clone()),
        virtual_name: mapping.map_prefix(working_directory).0.into_owned(),
    };

    assert_eq!(working_directory.remapped_path_if_available(), path("FOO"));

    // Unmapped absolute path
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::LocalPath(path("/foo/src/main.rs")),
            &working_directory
        ),
        RealFileName::Remapped {
            local_path: Some(path("/foo/src/main.rs")),
            virtual_name: path("FOO/src/main.rs")
        }
    );

    // Unmapped absolute path with unrelated working directory
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::LocalPath(path("/bar/src/main.rs")),
            &working_directory
        ),
        RealFileName::Remapped {
            local_path: Some(path("/bar/src/main.rs")),
            virtual_name: path("BAR/src/main.rs")
        }
    );

    // Already remapped absolute path, with unrelated working directory
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::Remapped {
                local_path: Some(path("/bar/src/main.rs")),
                virtual_name: path("BAR/src/main.rs"),
            },
            &working_directory
        ),
        RealFileName::Remapped {
            local_path: Some(path("/bar/src/main.rs")),
            virtual_name: path("BAR/src/main.rs")
        }
    );

    // Already remapped relative path
    assert_eq!(
        mapping.to_embeddable_absolute_path(
            RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") },
            &working_directory
        ),
        RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") }
    );
}

#[test]
fn path_prefix_remapping_reverse() {
    // Ignores options without alphanumeric chars.
    {
        let mapping = &FilePathMapping::new(
            vec![(path("abc"), path("/")), (path("def"), path("."))],
            FileNameDisplayPreference::Remapped,
            FileNameEmbeddablePreference::RemappedOnly,
        );

        assert_eq!(reverse_map_prefix(mapping, "/hello.rs"), None);
        assert_eq!(reverse_map_prefix(mapping, "./hello.rs"), None);
    }

    // Returns `None` if multiple options match.
    {
        let mapping = &FilePathMapping::new(
            vec![(path("abc"), path("/redacted")), (path("def"), path("/redacted"))],
            FileNameDisplayPreference::Remapped,
            FileNameEmbeddablePreference::RemappedOnly,
        );

        assert_eq!(reverse_map_prefix(mapping, "/redacted/hello.rs"), None);
    }

    // Distinct reverse mappings.
    {
        let mapping = &FilePathMapping::new(
            vec![(path("abc"), path("/redacted")), (path("def/ghi"), path("/fake/dir"))],
            FileNameDisplayPreference::Remapped,
            FileNameEmbeddablePreference::RemappedOnly,
        );

        assert_eq!(
            reverse_map_prefix(mapping, "/redacted/path/hello.rs"),
            Some(path_str("abc/path/hello.rs"))
        );
        assert_eq!(
            reverse_map_prefix(mapping, "/fake/dir/hello.rs"),
            Some(path_str("def/ghi/hello.rs"))
        );
    }
}

#[test]
fn test_next_point() {
    let sm = SourceMap::new(FilePathMapping::empty());
    sm.new_source_file(PathBuf::from("example.rs").into(), "a…b".to_string());

    // Dummy spans don't advance.
    let span = DUMMY_SP;
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 0);
    assert_eq!(span.hi().0, 0);

    // Span advance respect multi-byte character
    let span = Span::with_root_ctxt(BytePos(0), BytePos(1));
    assert_eq!(sm.span_to_snippet(span), Ok("a".to_string()));
    let span = sm.next_point(span);
    assert_eq!(sm.span_to_snippet(span), Ok("…".to_string()));
    assert_eq!(span.lo().0, 1);
    assert_eq!(span.hi().0, 4);

    // An empty span pointing just before a multi-byte character should
    // advance to contain the multi-byte character.
    let span = Span::with_root_ctxt(BytePos(1), BytePos(1));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 1);
    assert_eq!(span.hi().0, 4);

    let span = Span::with_root_ctxt(BytePos(1), BytePos(4));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 4);
    assert_eq!(span.hi().0, 5);

    // Reaching to the end of file, return a span that will get error with `span_to_snippet`
    let span = Span::with_root_ctxt(BytePos(4), BytePos(5));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 5);
    assert_eq!(span.hi().0, 6);
    assert!(sm.span_to_snippet(span).is_err());

    // Reaching to the end of file, return a span that will get error with `span_to_snippet`
    let span = Span::with_root_ctxt(BytePos(5), BytePos(5));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 5);
    assert_eq!(span.hi().0, 6);
    assert!(sm.span_to_snippet(span).is_err());
}

#[cfg(target_os = "linux")]
#[test]
fn read_binary_file_handles_lying_stat() {
    // read_binary_file tries to read the contents of a file into an Arc<[u8]> while
    // never having two copies of the data in memory at once. This is an optimization
    // to support include_bytes! with large files. But since Rust allocators are
    // sensitive to alignment, our implementation can't be bootstrapped off calling
    // std::fs::read. So we test that we have the same behavior even on files where
    // fs::metadata lies.

    // stat always says that /proc/self/cmdline is length 0, but it isn't.
    let cmdline = Path::new("/proc/self/cmdline");
    let len = std::fs::metadata(cmdline).unwrap().len() as usize;
    let real = std::fs::read(cmdline).unwrap();
    assert!(len < real.len());
    let bin = RealFileLoader.read_binary_file(cmdline).unwrap();
    assert_eq!(&real[..], &bin[..]);

    // stat always says that /sys/devices/system/cpu/kernel_max is the size of a block.
    let kernel_max = Path::new("/sys/devices/system/cpu/kernel_max");
    let len = std::fs::metadata(kernel_max).unwrap().len() as usize;
    let real = std::fs::read(kernel_max).unwrap();
    assert!(len > real.len());
    let bin = RealFileLoader.read_binary_file(kernel_max).unwrap();
    assert_eq!(&real[..], &bin[..]);
}
