use super::harness::*;
use cagire::forth::Value;

fn int(n: i64) -> Value {
    Value::Int(n, None)
}

#[test]
fn euclid_4_8() {
    expect_stack("4 8 euclid", &[int(0), int(2), int(4), int(6)]);
}

#[test]
fn euclid_3_8_tresillo() {
    expect_stack("3 8 euclid", &[int(0), int(3), int(6)]);
}

#[test]
fn euclid_5_8_cinquillo() {
    expect_stack("5 8 euclid", &[int(0), int(2), int(4), int(6), int(7)]);
}

#[test]
fn euclid_4_16() {
    expect_stack("4 16 euclid", &[int(0), int(4), int(8), int(12)]);
}

#[test]
fn euclid_5_16() {
    expect_stack("5 16 euclid", &[int(0), int(4), int(7), int(10), int(13)]);
}

#[test]
fn euclid_zero_hits() {
    expect_stack("0 8 euclid", &[]);
}

#[test]
fn euclid_zero_steps() {
    expect_stack("4 0 euclid", &[]);
}

#[test]
fn euclid_k_equals_n() {
    expect_stack("4 4 euclid", &[int(0), int(1), int(2), int(3)]);
}

#[test]
fn euclid_k_greater_than_n() {
    expect_stack("8 4 euclid", &[int(0), int(1), int(2), int(3)]);
}

#[test]
fn euclid_single_hit() {
    expect_stack("1 8 euclid", &[int(0)]);
}

#[test]
fn euclid_negative_k() {
    expect_error("-1 8 euclid", "k and n must be >= 0");
}

#[test]
fn euclid_negative_n() {
    expect_error("4 -8 euclid", "k and n must be >= 0");
}

#[test]
fn euclid_underflow() {
    expect_error("8 euclid", "stack underflow");
    expect_error("euclid", "stack underflow");
}

#[test]
fn euclidrot_basic() {
    expect_stack("3 8 1 euclidrot", &[int(2), int(5), int(7)]);
}

#[test]
fn euclidrot_zero_rotation() {
    expect_stack("3 8 0 euclidrot", &[int(0), int(3), int(6)]);
}

#[test]
fn euclidrot_full_rotation() {
    expect_stack("3 8 8 euclidrot", &[int(0), int(3), int(6)]);
}

#[test]
fn euclidrot_negative_r() {
    expect_error("3 8 -1 euclidrot", "k, n, and r must be >= 0");
}

#[test]
fn euclidrot_underflow() {
    expect_error("8 1 euclidrot", "stack underflow");
    expect_error("1 euclidrot", "stack underflow");
    expect_error("euclidrot", "stack underflow");
}

#[test]
fn euclid_with_at() {
    let outputs = expect_outputs("4 8 euclid at kick sound .", 4);
    assert_eq!(outputs.len(), 4);
}
