use maat_sdk::predicate::{EntityRef, MetricKind, Op, Predicate, Value};
use maat_sdk_derive::gate;

#[test]
fn distance_atom_lowers_to_value_distance() {
    let p = gate!(distance(SELF, TARGET, MetricKind::MotionLimited) <= 6);
    let expected = Predicate::Cmp(
        Value::Distance {
            from: EntityRef::Self_,
            to: EntityRef::Target,
            kind: MetricKind::MotionLimited,
        },
        Op::Le,
        Value::Const(6),
    );
    assert_eq!(p, expected);
}

#[test]
fn distance_supports_all_metric_kinds() {
    let _ = gate!(distance(SELF, TARGET, MetricKind::Unlimited) <= 6);
    let _ = gate!(distance(SELF, TARGET, MetricKind::VisionLimited) <= 12);
    let _ = gate!(distance(SELF, TARGET, MetricKind::MotionLimited) >= 1);
}

#[test]
fn distance_supports_all_comparison_ops() {
    let _ = gate!(distance(SELF, TARGET, MetricKind::MotionLimited) < 5);
    let _ = gate!(distance(SELF, TARGET, MetricKind::MotionLimited) <= 5);
    let _ = gate!(distance(SELF, TARGET, MetricKind::MotionLimited) == 5);
    let _ = gate!(distance(SELF, TARGET, MetricKind::MotionLimited) != 5);
    let _ = gate!(distance(SELF, TARGET, MetricKind::MotionLimited) >= 5);
    let _ = gate!(distance(SELF, TARGET, MetricKind::MotionLimited) > 5);
}

#[test]
fn distance_supports_const_kind_expression() {
    const MY_KIND: MetricKind = MetricKind::VisionLimited;
    let p = gate!(distance(SELF, TARGET, MY_KIND) <= 12);
    if let Predicate::Cmp(Value::Distance { kind, .. }, _, _) = p {
        assert_eq!(kind, MetricKind::VisionLimited);
    } else {
        panic!()
    }
}
