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,
        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,
        source_len.to_u32(),
        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[..]);
}
