use super::*;

fn rope(data: &[u8]) -> Rope {
    let mut r = Rope::new(None);
    r.push(data.to_vec());
    r
}

fn make_fastq(records: &[(&[u8], &[u8])]) -> Vec<u8> {
    let mut buf = Vec::new();
    for (seq, qual) in records {
        buf.extend_from_slice(b"@header\n");
        buf.extend_from_slice(seq);
        buf.push(b'\n');
        buf.extend_from_slice(b"+\n");
        buf.extend_from_slice(qual);
        buf.push(b'\n');
    }
    buf
}

fn flat(r: &Rope) -> Vec<u8> {
    r.fw_cursor().collect()
}

#[test]
fn single_record_no_boundary() {
    let buf = make_fastq(&[(b"ACGT", b"IIII")]);
    assert_eq!(end_of_last_fastq_entry(&rope(&buf)), None);
}

#[test]
fn two_records_cuts_at_second() {
    let buf = make_fastq(&[(b"ACGT", b"IIII"), (b"TTTT", b"HHHH")]);
    let r = rope(&buf);
    let pos = end_of_last_fastq_entry(&r).unwrap();
    assert_eq!(flat(&r)[pos], b'@');
    assert_eq!(
        &flat(&r)[pos..],
        make_fastq(&[(b"TTTT", b"HHHH")]).as_slice()
    );
}

#[test]
fn three_records_cuts_at_last() {
    let buf = make_fastq(&[(b"ACGT", b"IIII"), (b"CCCC", b"JJJJ"), (b"GGGG", b"KKKK")]);
    let r = rope(&buf);
    let pos = end_of_last_fastq_entry(&r).unwrap();
    assert_eq!(
        &flat(&r)[pos..],
        make_fastq(&[(b"GGGG", b"KKKK")]).as_slice()
    );
}

#[test]
fn at_sign_in_quality_does_not_confuse() {
    let buf = make_fastq(&[(b"ACGTACGT", b"@@@@IIII"), (b"TTTT", b"HHHH")]);
    let r = rope(&buf);
    let pos = end_of_last_fastq_entry(&r).unwrap();
    assert_eq!(
        &flat(&r)[pos..],
        make_fastq(&[(b"TTTT", b"HHHH")]).as_slice()
    );
}

#[test]
fn crlf_line_endings() {
    let data = b"@h\r\nACGT\r\n+\r\nIIII\r\n@h\r\nTTTT\r\n+\r\nHHHH\r\n";
    let r = rope(data);
    let pos = end_of_last_fastq_entry(&r).unwrap();
    assert_eq!(flat(&r)[pos], b'@');
    assert_eq!(&flat(&r)[pos..], b"@h\r\nTTTT\r\n+\r\nHHHH\r\n");
}
