mod common;

use randomorg_rpc::{
    BlobFormat, BlobsParams, DecimalFractionsParams, GaussiansParams,
    IntegerSequencesUniformParams, IntegersParams, SignedExtras, StringsParams, UuidsParams,
};
use serde_json::json;

#[tokio::test]
async fn signed_integers_roundtrip() {
    let c = common::client();
    let r = c
        .generate_signed_integers(IntegersParams::new(5, 1, 100), SignedExtras::new())
        .await
        .unwrap();

    let data: Vec<i64> = r.data().unwrap();
    assert_eq!(data.len(), 5);

    let v = c.verify_signature(&r.random.0, &r.signature).await.unwrap();
    assert!(v.authenticity, "server says signature not authentic");
}

#[tokio::test]
async fn signed_integer_sequences_uniform() {
    let c = common::client();
    let r = c
        .generate_signed_integer_sequences_uniform(
            IntegerSequencesUniformParams::new(2, 3, 1, 10),
            SignedExtras::new(),
        )
        .await
        .unwrap();
    let data: Vec<Vec<i64>> = r.data().unwrap();
    assert_eq!(data.len(), 2);
    assert_eq!(data[0].len(), 3);
    let v = c.verify_signature(&r.random.0, &r.signature).await.unwrap();
    assert!(v.authenticity);
}

#[tokio::test]
async fn signed_decimal_fractions() {
    let c = common::client();
    let r = c
        .generate_signed_decimal_fractions(DecimalFractionsParams::new(3, 6), SignedExtras::new())
        .await
        .unwrap();
    let data: Vec<f64> = r.data().unwrap();
    assert_eq!(data.len(), 3);
    let v = c.verify_signature(&r.random.0, &r.signature).await.unwrap();
    assert!(v.authenticity);
}

#[tokio::test]
async fn signed_gaussians() {
    let c = common::client();
    let r = c
        .generate_signed_gaussians(GaussiansParams::new(3, 0.0, 1.0, 5), SignedExtras::new())
        .await
        .unwrap();
    let data: Vec<f64> = r.data().unwrap();
    assert_eq!(data.len(), 3);
}

#[tokio::test]
async fn signed_strings() {
    let c = common::client();
    let r = c
        .generate_signed_strings(StringsParams::new(2, 4, "abcdef"), SignedExtras::new())
        .await
        .unwrap();
    let data: Vec<String> = r.data().unwrap();
    assert_eq!(data.len(), 2);
}

#[tokio::test]
async fn signed_uuids() {
    let c = common::client();
    let r = c
        .generate_signed_uuids(UuidsParams::new(1), SignedExtras::new())
        .await
        .unwrap();
    let data: Vec<String> = r.data().unwrap();
    assert_eq!(data.len(), 1);
}

#[tokio::test]
async fn signed_blobs() {
    let c = common::client();
    let r = c
        .generate_signed_blobs(
            BlobsParams::new(1, 32).format(BlobFormat::Base64),
            SignedExtras::new(),
        )
        .await
        .unwrap();
    let data: Vec<String> = r.data().unwrap();
    assert_eq!(data.len(), 1);
}

#[tokio::test]
async fn signed_with_user_data_and_get_result() {
    let c = common::client();
    let extras = SignedExtras::new().user_data(json!({"label": "rust-test"}));
    let r = c
        .generate_signed_integers(IntegersParams::new(3, 1, 6), extras)
        .await
        .unwrap();
    let serial = r.serial_number().expect("serialNumber");
    let again = c.get_result(serial).await.unwrap();
    assert!(again.get("random").is_some());
    assert!(again.get("signature").is_some());
}
