// run-pass
// ignore-cross-compile

use std::env;
use std::fs::File;
use std::io;
use std::io::{Read, Write};
use std::process::{Command, Stdio};
use std::path::PathBuf;

fn main() {
    if env::args().len() > 1 {
        child().unwrap()
    } else {
        parent().unwrap()
    }
}

fn parent() -> io::Result<()> {
    let td = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
    let input = td.join("stdio-from-input");
    let output = td.join("stdio-from-output");

    File::create(&input)?.write_all(b"foo\n")?;

    // Set up this chain:
    //     $ me <file | me | me >file
    // ... to duplicate each line 8 times total.

    let mut child1 = Command::new(env::current_exe()?)
        .arg("first")
        .stdin(File::open(&input)?) // tests File::into()
        .stdout(Stdio::piped())
        .spawn()?;

    let mut child3 = Command::new(env::current_exe()?)
        .arg("third")
        .stdin(Stdio::piped())
        .stdout(File::create(&output)?) // tests File::into()
        .spawn()?;

    // Started out of order so we can test both `ChildStdin` and `ChildStdout`.
    let mut child2 = Command::new(env::current_exe()?)
        .arg("second")
        .stdin(child1.stdout.take().unwrap()) // tests ChildStdout::into()
        .stdout(child3.stdin.take().unwrap()) // tests ChildStdin::into()
        .spawn()?;

    assert!(child1.wait()?.success());
    assert!(child2.wait()?.success());
    assert!(child3.wait()?.success());

    let mut data = String::new();
    File::open(&output)?.read_to_string(&mut data)?;
    for line in data.lines() {
        assert_eq!(line, "foo");
    }
    assert_eq!(data.lines().count(), 8);
    Ok(())
}

fn child() -> io::Result<()> {
    // double everything
    let mut input = vec![];
    io::stdin().read_to_end(&mut input)?;
    io::stdout().write_all(&input)?;
    io::stdout().write_all(&input)?;
    Ok(())
}
