//! Tests for the tick channel flavor.

#[macro_use]
extern crate crossbeam_channel;
extern crate crossbeam_utils;
extern crate rand;

use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use std::thread;
use std::time::{Duration, Instant};

use crossbeam_channel::{after, tick, Select, TryRecvError};
use crossbeam_utils::thread::scope;

fn ms(ms: u64) -> Duration {
    Duration::from_millis(ms)
}

#[test]
fn fire() {
    let start = Instant::now();
    let r = tick(ms(50));

    assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
    thread::sleep(ms(100));

    let fired = r.try_recv().unwrap();
    assert!(start < fired);
    assert!(fired - start >= ms(50));

    let now = Instant::now();
    assert!(fired < now);
    assert!(now - fired >= ms(50));

    assert_eq!(r.try_recv(), Err(TryRecvError::Empty));

    select! {
        recv(r) -> _ => panic!(),
        default => {}
    }

    select! {
        recv(r) -> _ => {}
        recv(tick(ms(200))) -> _ => panic!(),
    }
}

#[test]
fn intervals() {
    let start = Instant::now();
    let r = tick(ms(50));

    let t1 = r.recv().unwrap();
    assert!(start + ms(50) <= t1);
    assert!(start + ms(100) > t1);

    thread::sleep(ms(300));
    let t2 = r.try_recv().unwrap();
    assert!(start + ms(100) <= t2);
    assert!(start + ms(150) > t2);

    assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
    let t3 = r.recv().unwrap();
    assert!(start + ms(400) <= t3);
    assert!(start + ms(450) > t3);

    assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
}

#[test]
fn capacity() {
    const COUNT: usize = 10;

    for i in 0..COUNT {
        let r = tick(ms(i as u64));
        assert_eq!(r.capacity(), Some(1));
    }
}

#[test]
fn len_empty_full() {
    let r = tick(ms(50));

    assert_eq!(r.len(), 0);
    assert_eq!(r.is_empty(), true);
    assert_eq!(r.is_full(), false);

    thread::sleep(ms(100));

    assert_eq!(r.len(), 1);
    assert_eq!(r.is_empty(), false);
    assert_eq!(r.is_full(), true);

    r.try_recv().unwrap();

    assert_eq!(r.len(), 0);
    assert_eq!(r.is_empty(), true);
    assert_eq!(r.is_full(), false);
}

#[test]
fn try_recv() {
    let r = tick(ms(200));
    assert!(r.try_recv().is_err());

    thread::sleep(ms(100));
    assert!(r.try_recv().is_err());

    thread::sleep(ms(200));
    assert!(r.try_recv().is_ok());
    assert!(r.try_recv().is_err());

    thread::sleep(ms(200));
    assert!(r.try_recv().is_ok());
    assert!(r.try_recv().is_err());
}

#[test]
fn recv() {
    let start = Instant::now();
    let r = tick(ms(50));

    let fired = r.recv().unwrap();
    assert!(start < fired);
    assert!(fired - start >= ms(50));

    let now = Instant::now();
    assert!(fired < now);
    assert!(now - fired < fired - start);

    assert_eq!(r.try_recv(), Err(TryRecvError::Empty));
}

#[test]
fn recv_timeout() {
    let start = Instant::now();
    let r = tick(ms(200));

    assert!(r.recv_timeout(ms(100)).is_err());
    let now = Instant::now();
    assert!(now - start >= ms(100));
    assert!(now - start <= ms(150));

    let fired = r.recv_timeout(ms(200)).unwrap();
    assert!(fired - start >= ms(200));
    assert!(fired - start <= ms(250));

    assert!(r.recv_timeout(ms(100)).is_err());
    let now = Instant::now();
    assert!(now - start >= ms(300));
    assert!(now - start <= ms(350));

    let fired = r.recv_timeout(ms(200)).unwrap();
    assert!(fired - start >= ms(400));
    assert!(fired - start <= ms(450));
}

#[test]
fn recv_two() {
    let r1 = tick(ms(50));
    let r2 = tick(ms(50));

    scope(|scope| {
        scope.spawn(|_| {
            for _ in 0..10 {
                select! {
                    recv(r1) -> _ => {}
                    recv(r2) -> _ => {}
                }
            }
        });
        scope.spawn(|_| {
            for _ in 0..10 {
                select! {
                    recv(r1) -> _ => {}
                    recv(r2) -> _ => {}
                }
            }
        });
    })
    .unwrap();
}

#[test]
fn recv_race() {
    select! {
        recv(tick(ms(50))) -> _ => {}
        recv(tick(ms(100))) -> _ => panic!(),
    }

    select! {
        recv(tick(ms(100))) -> _ => panic!(),
        recv(tick(ms(50))) -> _ => {}
    }
}

#[test]
fn stress_default() {
    const COUNT: usize = 10;

    for _ in 0..COUNT {
        select! {
            recv(tick(ms(0))) -> _ => {}
            default => panic!(),
        }
    }

    for _ in 0..COUNT {
        select! {
            recv(tick(ms(100))) -> _ => panic!(),
            default => {}
        }
    }
}

#[test]
fn select() {
    const THREADS: usize = 4;

    let hits = AtomicUsize::new(0);
    let r1 = tick(ms(200));
    let r2 = tick(ms(300));

    scope(|scope| {
        for _ in 0..THREADS {
            scope.spawn(|_| {
                let timeout = after(ms(1100));
                loop {
                    let mut sel = Select::new();
                    let oper1 = sel.recv(&r1);
                    let oper2 = sel.recv(&r2);
                    let oper3 = sel.recv(&timeout);
                    let oper = sel.select();
                    match oper.index() {
                        i if i == oper1 => {
                            oper.recv(&r1).unwrap();
                            hits.fetch_add(1, Ordering::SeqCst);
                        }
                        i if i == oper2 => {
                            oper.recv(&r2).unwrap();
                            hits.fetch_add(1, Ordering::SeqCst);
                        }
                        i if i == oper3 => {
                            oper.recv(&timeout).unwrap();
                            break;
                        }
                        _ => unreachable!(),
                    }
                }
            });
        }
    })
    .unwrap();

    assert_eq!(hits.load(Ordering::SeqCst), 8);
}

#[test]
fn ready() {
    const THREADS: usize = 4;

    let hits = AtomicUsize::new(0);
    let r1 = tick(ms(200));
    let r2 = tick(ms(300));

    scope(|scope| {
        for _ in 0..THREADS {
            scope.spawn(|_| {
                let timeout = after(ms(1100));
                'outer: loop {
                    let mut sel = Select::new();
                    sel.recv(&r1);
                    sel.recv(&r2);
                    sel.recv(&timeout);
                    loop {
                        match sel.ready() {
                            0 => {
                                if r1.try_recv().is_ok() {
                                    hits.fetch_add(1, Ordering::SeqCst);
                                    break;
                                }
                            }
                            1 => {
                                if r2.try_recv().is_ok() {
                                    hits.fetch_add(1, Ordering::SeqCst);
                                    break;
                                }
                            }
                            2 => {
                                if timeout.try_recv().is_ok() {
                                    break 'outer;
                                }
                            }
                            _ => unreachable!(),
                        }
                    }
                }
            });
        }
    })
    .unwrap();

    assert_eq!(hits.load(Ordering::SeqCst), 8);
}

#[test]
fn fairness() {
    const COUNT: usize = 30;

    for &dur in &[0, 1] {
        let mut hits = [0usize; 2];

        for _ in 0..COUNT {
            let r1 = tick(ms(dur));
            let r2 = tick(ms(dur));

            for _ in 0..COUNT {
                select! {
                    recv(r1) -> _ => hits[0] += 1,
                    recv(r2) -> _ => hits[1] += 1,
                }
            }
        }

        assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
    }
}

#[test]
fn fairness_duplicates() {
    const COUNT: usize = 30;

    for &dur in &[0, 1] {
        let mut hits = [0usize; 5];

        for _ in 0..COUNT {
            let r = tick(ms(dur));

            for _ in 0..COUNT {
                select! {
                    recv(r) -> _ => hits[0] += 1,
                    recv(r) -> _ => hits[1] += 1,
                    recv(r) -> _ => hits[2] += 1,
                    recv(r) -> _ => hits[3] += 1,
                    recv(r) -> _ => hits[4] += 1,
                }
            }
        }

        assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2));
    }
}
