mod testprotocol;
mod testsupport;

use crate::testprotocol::acme::user::v1::{
    Bucket, TypeSaladBooleanType, TypeSaladCharacterTypes, TypeSaladNumericFloatingPointTypes,
    TypeSaladNumericIntegerTypes, TypeSaladUuidTypes,
};
use crate::testsupport::get_config_store;
use pbbson::{Model, bson};
use xid;

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn can_create_and_read_boolean_type() {
    let config_store = get_config_store!();
    let boolean_type = TypeSaladBooleanType { col_1: true };
    let boolean_type_final: TypeSaladBooleanType = config_store
        .create(Bucket::TypeSaladBooleanTypes, Model::try_from(&boolean_type).unwrap())
        .await
        .expect("Expected to be able to create a record with the boolean type")
        .try_into()
        .expect("Expected to be able to deserialize the boolean type");
    assert_eq!(boolean_type, boolean_type_final);
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn can_create_and_read_character_types() {
    let config_store = get_config_store!();
    let character_types = TypeSaladCharacterTypes {
        col_1: xid::new().to_string(),
        col_2: xid::new().to_string(),
        col_3: xid::new().to_string(),
        col_4: xid::new().to_string(),
    };
    let character_types_final: TypeSaladCharacterTypes = config_store
        .create(
            Bucket::TypeSaladCharacterTypes,
            Model::try_from(&character_types).unwrap(),
        )
        .await
        .expect("Expected to be able to create a record with each character type")
        .try_into()
        .expect("Expected to be able to deserialize each character type");
    assert_eq!(character_types, character_types_final);
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn can_create_and_read_numeric_arbitrary_precision_types() {
    let config_store = get_config_store!();
    let integer_types = TypeSaladNumericFloatingPointTypes {
        id: xid::new().to_string(),
        col_2: 123.4,
        col_3: 234.0,
    };
    config_store
        .create(
            Bucket::TypeSaladNumericArbitraryPrecisionTypes,
            Model::try_from(&integer_types).unwrap(),
        )
        .await
        .expect("Expected to be able to create a record with each numeric floating point type");
    let floating_point_types_reloaded: TypeSaladNumericFloatingPointTypes = config_store
        .find(Bucket::TypeSaladNumericArbitraryPrecisionTypes, &integer_types.id)
        .await
        .expect("Expected to be able to find a record with each numeric floating point type")
        .try_into()
        .expect("Expected to be able to deserialize each numeric floating point type");
    assert_eq!(integer_types, floating_point_types_reloaded);
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn can_create_and_read_numeric_floating_point_types() {
    let config_store = get_config_store!();
    let integer_types = TypeSaladNumericFloatingPointTypes {
        id: xid::new().to_string(),
        col_2: 123.4,
        col_3: 234.5,
    };
    config_store
        .create(
            Bucket::TypeSaladNumericFloatingPointTypes,
            Model::try_from(&integer_types).unwrap(),
        )
        .await
        .expect("Expected to be able to create a record with each numeric floating point type");
    let floating_point_types_reloaded: TypeSaladNumericFloatingPointTypes = config_store
        .find(Bucket::TypeSaladNumericFloatingPointTypes, &integer_types.id)
        .await
        .expect("Expected to be able to find a record with each numeric floating point type")
        .try_into()
        .expect("Expected to be able to deserialize each numeric floating point type");
    assert_eq!(integer_types, floating_point_types_reloaded);
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn can_create_and_read_numeric_integer_types() {
    let config_store = get_config_store!();
    let integer_types = TypeSaladNumericIntegerTypes {
        id: xid::new().to_string(),
        col_2: 123,
        col_3: 234,
        col_4: "345".to_string(),
    };
    config_store
        .create(
            Bucket::TypeSaladNumericIntegerTypes,
            Model::try_from(&integer_types).unwrap(),
        )
        .await
        .expect("Expected to be able to create a record with each numeric integer type");
    let integer_types_reloaded: TypeSaladNumericIntegerTypes = config_store
        .find(Bucket::TypeSaladNumericIntegerTypes, &integer_types.id)
        .await
        .expect("Expected to be able to find a record with each numeric integer type")
        .try_into()
        .expect("Expected to be able to deserialize each numeric integer type");
    assert_eq!(integer_types, integer_types_reloaded);
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn can_create_and_read_numeric_serial_types() {
    let config_store = get_config_store!();
    let integer_types = TypeSaladNumericIntegerTypes {
        id: xid::new().to_string(),
        col_2: 123,
        col_3: 234,
        col_4: "345".to_string(),
    };
    config_store
        .create(
            Bucket::TypeSaladNumericSerialTypes,
            Model::try_from(&integer_types).unwrap(),
        )
        .await
        .expect("Expected to be able to create a record with each numeric serial type");
    let integer_types_reloaded: TypeSaladNumericIntegerTypes = config_store
        .find(Bucket::TypeSaladNumericSerialTypes, &integer_types.id)
        .await
        .expect("Expected to be able to find a record with each numeric serial type")
        .try_into()
        .expect("Expected to be able to deserialize each numeric serial type");
    assert_eq!(integer_types, integer_types_reloaded);
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn can_create_and_read_uuid_type() {
    let config_store = get_config_store!();
    let uuid_types = TypeSaladUuidTypes {
        id: bson::Uuid::new().to_string(),
    };
    config_store
        .create(Bucket::TypeSaladUuidTypes, Model::try_from(&uuid_types).unwrap())
        .await
        .expect("Expected to be able to create a record with uuid type");
    let uuid_types_reloaded: TypeSaladUuidTypes = config_store
        .find(Bucket::TypeSaladUuidTypes, &uuid_types.id)
        .await
        .expect("Expected to be able to find a record with uuid type")
        .try_into()
        .expect("Expected to be able to deserialize uuid type");
    assert_eq!(uuid_types, uuid_types_reloaded);
}
