use std::io::prelude::*;

use libc::off_t;
use nix::sys::sendfile::*;
use tempfile::tempfile;

cfg_if! {
    if #[cfg(linux_android)] {
        use nix::unistd::{pipe, read};
        use std::os::unix::io::AsRawFd;
    } else if #[cfg(any(freebsdlike, apple_targets, solarish))] {
        use std::net::Shutdown;
        use std::os::unix::net::UnixStream;
    }
}

#[cfg(linux_android)]
#[test]
fn test_sendfile_linux() {
    const CONTENTS: &[u8] = b"abcdef123456";
    let mut tmp = tempfile().unwrap();
    tmp.write_all(CONTENTS).unwrap();

    let (rd, wr) = pipe().unwrap();
    let mut offset: off_t = 5;
    let res = sendfile(&wr, &tmp, Some(&mut offset), 2).unwrap();

    assert_eq!(2, res);

    let mut buf = [0u8; 1024];
    assert_eq!(2, read(rd.as_raw_fd(), &mut buf).unwrap());
    assert_eq!(b"f1", &buf[0..2]);
    assert_eq!(7, offset);
}

#[cfg(target_os = "linux")]
#[test]
fn test_sendfile64_linux() {
    const CONTENTS: &[u8] = b"abcdef123456";
    let mut tmp = tempfile().unwrap();
    tmp.write_all(CONTENTS).unwrap();

    let (rd, wr) = pipe().unwrap();
    let mut offset: libc::off64_t = 5;
    let res = sendfile64(&wr, &tmp, Some(&mut offset), 2).unwrap();

    assert_eq!(2, res);

    let mut buf = [0u8; 1024];
    assert_eq!(2, read(rd.as_raw_fd(), &mut buf).unwrap());
    assert_eq!(b"f1", &buf[0..2]);
    assert_eq!(7, offset);
}

#[cfg(target_os = "freebsd")]
#[test]
fn test_sendfile_freebsd() {
    // Declare the content
    let header_strings =
        ["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"];
    let body = "Xabcdef123456";
    let body_offset = 1;
    let trailer_strings = ["\n", "Served by Make Believe\n"];

    // Write the body to a file
    let mut tmp = tempfile().unwrap();
    tmp.write_all(body.as_bytes()).unwrap();

    // Prepare headers and trailers for sendfile
    let headers: Vec<&[u8]> =
        header_strings.iter().map(|s| s.as_bytes()).collect();
    let trailers: Vec<&[u8]> =
        trailer_strings.iter().map(|s| s.as_bytes()).collect();

    // Prepare socket pair
    let (mut rd, wr) = UnixStream::pair().unwrap();

    // Call the test method
    let (res, bytes_written) = sendfile(
        &tmp,
        &wr,
        body_offset as off_t,
        None,
        Some(headers.as_slice()),
        Some(trailers.as_slice()),
        SfFlags::empty(),
        0,
    );
    assert!(res.is_ok());
    wr.shutdown(Shutdown::Both).unwrap();

    // Prepare the expected result
    let expected_string = header_strings.concat()
        + &body[body_offset..]
        + &trailer_strings.concat();

    // Verify the message that was sent
    assert_eq!(bytes_written as usize, expected_string.as_bytes().len());

    let mut read_string = String::new();
    let bytes_read = rd.read_to_string(&mut read_string).unwrap();
    assert_eq!(bytes_written as usize, bytes_read);
    assert_eq!(expected_string, read_string);
}

#[cfg(target_os = "dragonfly")]
#[test]
fn test_sendfile_dragonfly() {
    // Declare the content
    let header_strings =
        ["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"];
    let body = "Xabcdef123456";
    let body_offset = 1;
    let trailer_strings = ["\n", "Served by Make Believe\n"];

    // Write the body to a file
    let mut tmp = tempfile().unwrap();
    tmp.write_all(body.as_bytes()).unwrap();

    // Prepare headers and trailers for sendfile
    let headers: Vec<&[u8]> =
        header_strings.iter().map(|s| s.as_bytes()).collect();
    let trailers: Vec<&[u8]> =
        trailer_strings.iter().map(|s| s.as_bytes()).collect();

    // Prepare socket pair
    let (mut rd, wr) = UnixStream::pair().unwrap();

    // Call the test method
    let (res, bytes_written) = sendfile(
        &tmp,
        &wr,
        body_offset as off_t,
        None,
        Some(headers.as_slice()),
        Some(trailers.as_slice()),
    );
    assert!(res.is_ok());
    wr.shutdown(Shutdown::Both).unwrap();

    // Prepare the expected result
    let expected_string = header_strings.concat()
        + &body[body_offset..]
        + &trailer_strings.concat();

    // Verify the message that was sent
    assert_eq!(bytes_written as usize, expected_string.as_bytes().len());

    let mut read_string = String::new();
    let bytes_read = rd.read_to_string(&mut read_string).unwrap();
    assert_eq!(bytes_written as usize, bytes_read);
    assert_eq!(expected_string, read_string);
}

#[cfg(apple_targets)]
#[test]
fn test_sendfile_darwin() {
    // Declare the content
    let header_strings =
        vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"];
    let body = "Xabcdef123456";
    let body_offset = 1;
    let trailer_strings = vec!["\n", "Served by Make Believe\n"];

    // Write the body to a file
    let mut tmp = tempfile().unwrap();
    tmp.write_all(body.as_bytes()).unwrap();

    // Prepare headers and trailers for sendfile
    let headers: Vec<&[u8]> =
        header_strings.iter().map(|s| s.as_bytes()).collect();
    let trailers: Vec<&[u8]> =
        trailer_strings.iter().map(|s| s.as_bytes()).collect();

    // Prepare socket pair
    let (mut rd, wr) = UnixStream::pair().unwrap();

    // Call the test method
    let (res, bytes_written) = sendfile(
        &tmp,
        &wr,
        body_offset as off_t,
        None,
        Some(headers.as_slice()),
        Some(trailers.as_slice()),
    );
    assert!(res.is_ok());
    wr.shutdown(Shutdown::Both).unwrap();

    // Prepare the expected result
    let expected_string = header_strings.concat()
        + &body[body_offset..]
        + &trailer_strings.concat();

    // Verify the message that was sent
    assert_eq!(bytes_written as usize, expected_string.as_bytes().len());

    let mut read_string = String::new();
    let bytes_read = rd.read_to_string(&mut read_string).unwrap();
    assert_eq!(bytes_written as usize, bytes_read);
    assert_eq!(expected_string, read_string);
}

#[cfg(solarish)]
#[test]
fn test_sendfilev() {
    use std::os::fd::AsFd;
    // Declare the content
    let header_strings =
        ["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"];
    let body = "Xabcdef123456";
    let body_offset = 1usize;
    let trailer_strings = ["\n", "Served by Make Believe\n"];

    // Write data to files
    let mut header_data = tempfile().unwrap();
    header_data
        .write_all(header_strings.concat().as_bytes())
        .unwrap();
    let mut body_data = tempfile().unwrap();
    body_data.write_all(body.as_bytes()).unwrap();
    let mut trailer_data = tempfile().unwrap();
    trailer_data
        .write_all(trailer_strings.concat().as_bytes())
        .unwrap();
    let (mut rd, wr) = UnixStream::pair().unwrap();
    let vec: &[SendfileVec] = &[
        SendfileVec::new(
            header_data.as_fd(),
            0,
            header_strings.iter().map(|s| s.len()).sum(),
        ),
        SendfileVec::new(
            body_data.as_fd(),
            body_offset as off_t,
            body.len() - body_offset,
        ),
        SendfileVec::new(
            trailer_data.as_fd(),
            0,
            trailer_strings.iter().map(|s| s.len()).sum(),
        ),
    ];

    let (res, bytes_written) = sendfilev(&wr, vec);
    assert!(res.is_ok());
    wr.shutdown(Shutdown::Both).unwrap();

    // Prepare the expected result
    let expected_string = header_strings.concat()
        + &body[body_offset..]
        + &trailer_strings.concat();

    // Verify the message that was sent
    assert_eq!(bytes_written, expected_string.as_bytes().len());

    let mut read_string = String::new();
    let bytes_read = rd.read_to_string(&mut read_string).unwrap();
    assert_eq!(bytes_written, bytes_read);
    assert_eq!(expected_string, read_string);
}
