// Example: Using WritePropertyMultiple for efficient bulk writes
//
// This example demonstrates how to use the WritePropertyMultiple service
// to write multiple properties across multiple objects in a single BACnet request.
// This is much more efficient than calling write_property multiple times.

use bacnet_emb::{
    application_protocol::primitives::data_value::{
        ApplicationDataValueWrite, Enumerated,
    },
    application_protocol::services::write_property_multiple::{
        WritePropertyMultiple, WritePropertyMultipleObject, WritePropertyRequest,
    },
    common::object_id::{ObjectId, ObjectType},
    common::property_id::PropertyId,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize your network IO implementation
    // let io = YourNetworkIo::new();
    // let bacnet = Bacnet::new(io);

    // Example 1: Write multiple properties to a single object
    let writes_single_object = vec![
        WritePropertyRequest::new(
            PropertyId::PropPresentValue,
            None,
            ApplicationDataValueWrite::Real(22.5),
            None,
        ),
        WritePropertyRequest::new(
            PropertyId::PropPriorityArray,
            None,
            ApplicationDataValueWrite::Boolean(true),
            Some(8),
        ),
    ];

    let object1 = WritePropertyMultipleObject::new(
        ObjectId::new(ObjectType::ObjectAnalogInput, 0),
        writes_single_object,
    );

    // Example 2: Write properties to multiple objects
    let writes_object2 = vec![WritePropertyRequest::new(
        PropertyId::PropPresentValue,
        None,
        ApplicationDataValueWrite::Enumerated(Enumerated::Unknown(1)),
        None,
    )];

    let writes_object3 = vec![
        WritePropertyRequest::new(
            PropertyId::PropPresentValue,
            None,
            ApplicationDataValueWrite::Real(18.3),
            None,
        ),
        WritePropertyRequest::new(
            PropertyId::PropDeadband,
            None,
            ApplicationDataValueWrite::Real(0.5),
            None,
        ),
    ];

    let object2 = WritePropertyMultipleObject::new(
        ObjectId::new(ObjectType::ObjectBinaryInput, 1),
        writes_object2,
    );

    let object3 = WritePropertyMultipleObject::new(
        ObjectId::new(ObjectType::ObjectAnalogInput, 2),
        writes_object3,
    );

    // Combine all objects into a single WritePropertyMultiple request
    let request = WritePropertyMultiple::new(vec![object1, object2, object3]);

    // Send the request
    // let mut buffer = [0u8; 1500];
    // bacnet
    //     .write_property_multiple(&mut buffer, request, None)
    //     .await?;

    println!("WritePropertyMultiple example completed successfully!");
    Ok(())
}

// Example for no_std environment (without alloc feature)
#[cfg(not(feature = "alloc"))]
fn no_std_example() {
    use core::borrow::Borrow;

    // For no_std, use static arrays instead of Vec
    let write1 = WritePropertyRequest::new(
        PropertyId::PropPresentValue,
        None,
        ApplicationDataValueWrite::Real(22.5),
        None,
    );

    let write2 = WritePropertyRequest::new(
        PropertyId::PropPriorityArray,
        None,
        ApplicationDataValueWrite::Boolean(true),
        Some(8),
    );

    let writes = &[write1, write2];

    let object = WritePropertyMultipleObject::new(
        ObjectId::new(ObjectType::ObjectAnalogInput, 0),
        writes,
    );

    let objects = &[object];

    let request = WritePropertyMultiple::new(objects);

    // Send the request
    // bacnet.write_property_multiple(&mut buffer, request, None).await?;
}

// Benefits of using WritePropertyMultiple:
//
// 1. **Efficiency**: Reduces network overhead by combining multiple writes into a single request
// 2. **Performance**: Fewer round-trips between client and server
// 3. **Atomicity**: All writes in the request are processed together
// 4. **Scalability**: Can write to multiple objects and properties in one operation
//
// Comparison:
// - Individual writes: N objects × M properties = N×M network requests
// - Bulk write: 1 network request for all N objects and M properties
//
// Use cases:
// - Configuring multiple points on a controller
// - Batch updating sensor values
// - Initializing device properties
// - Synchronized control of multiple outputs
