mod utils;
use mquery::query::{
    fns::{self, aggregate, rollup, transform},
    Duration, Metric, Unit,
};

#[cfg(feature = "metricsql")]
use fns::label;

macro_rules! rollup_tests {
    ($($fn_name:ident),+) => {
        $(#[tokio::test]
        async fn $fn_name() {
            let query = rollup::$fn_name(Metric::new("test_metric").lookback(Duration(1, Unit::Day)));
            utils::send_query(query).await.unwrap();
        })+
    };
}

macro_rules! aggr_tests {
    ($($fn_name: tt),+) => {
        $(#[tokio::test]
        async fn $fn_name() {
            let query = aggregate::$fn_name(Metric::new("test_metric"));
            utils::send_query(query).await.unwrap();
        })+
    };
}

#[cfg(feature = "metricsql")]
macro_rules! label_tests {
    ($($fn_name: tt),+) => {
        $(#[tokio::test]
        async fn $fn_name() {
            let query = label::$fn_name(Metric::new("metric"), &["label", "label2"]);
            utils::send_query(query).await.unwrap();
        })+
    };
}

macro_rules! transform_tests {
    ($($fn_name: tt),+) => {
        $(#[tokio::test]
        async fn $fn_name() {
            let query = transform::$fn_name(Metric::new("metric"));
            utils::send_query(query).await.unwrap();
        })+
    };
}

aggr_tests!(sum, min, max, avg, group, stddev, stdvar, count);

#[tokio::test]
async fn aggr_count_values() {
    let query = aggregate::count_values("label", Metric::new("test_metric"));
    utils::send_query(query).await.unwrap();
}

#[tokio::test]
async fn aggr_topk() {
    let query = aggregate::topk(10, Metric::new("test_metric"));
    utils::send_query(query).await.unwrap();
}

#[tokio::test]
async fn aggr_bottomk() {
    let query = aggregate::bottomk(10, Metric::new("test_metric"));
    utils::send_query(query).await.unwrap();
}

#[tokio::test]
async fn aggr_quantile() {
    let query = aggregate::quantile(0.5, Metric::new("test_metric"));
    utils::send_query(query).await.unwrap();
}

rollup_tests!(
    avg_over_time,
    min_over_time,
    max_over_time,
    sum_over_time,
    count_over_time,
    stddev_over_time,
    stdvar_over_time,
    present_over_time,
    last_over_time,
    timestamp
);

#[tokio::test]
async fn quantile_over_time() {
    let query = rollup::quantile_over_time(
        0.1,
        Metric::new("test_metric").lookback(Duration(1, Unit::Day)),
    );
    utils::send_query(query).await.unwrap();
}

#[cfg(feature = "metricsql")]
#[tokio::test]
async fn mql_label_map() {
    let query = label::mql_label_map(
        Metric::new("metric"),
        "label",
        &["source", "destination", "source2", "destination2"],
    );
    utils::send_query(query).await.unwrap();
}

#[cfg(feature = "metricsql")]
#[tokio::test]
async fn mql_alias() {
    let query = label::mql_alias(Metric::new("metric"), "alias");
    utils::send_query(query).await.unwrap();
}

#[cfg(feature = "metricsql")]
label_tests!(
    mql_label_set,
    mql_sort_by_label,
    mql_sort_by_label_desc,
    mql_sort_by_label_numeric,
    mql_sort_by_label_numeric_desc
);

transform_tests!(abs, absent, ceil, changes, delta, exp, floor, sort, sort_desc, sqrt);

#[cfg(feature = "metricsql")]
#[tokio::test]
async fn trans_limit_offset() {
    let query = transform::mql_limit_offset(1, 2, Metric::new("metric")).to_string();
    utils::send_query(query).await.unwrap();
}

#[cfg(feature = "metricsql")]
#[tokio::test]
async fn trans_union() {
    let query = transform::mql_union(&[Metric::new("metric"), Metric::new("metric2")]).to_string();
    utils::send_query(query).await.unwrap();
}

#[tokio::test]
async fn trans_round() {
    let query = transform::round(Metric::new("metric"), Some(1.0));
    utils::send_query(query).await.unwrap();
}

#[tokio::test]
async fn trans_vector() {
    let query = transform::vector(1.0);
    utils::send_query(query).await.unwrap();
}