/*
DO NOT MODIFY THIS FILE {# unless you see this comment #}.  It is automatically generated and changes will be over-written
on the next generation.

It contains enumerations used by the {{stinger.name}} interface.
*/
use futures::{executor::block_on};
use mqttier::MqttierClient;
use {{stinger.rust.server_package_name}}::{{stinger.rust.server_struct_name}};
use tokio::time::{sleep, Duration};

#[allow(unused_imports)]
use {{stinger.rust.common_package_name}}::payloads::{MethodResultCode, *};

{%for method_name, method in stinger.methods.items()%}
fn {{method_name|snake_case}}_handler({%for arg in method.arg_list%}_{{arg.name|snake_case}}: {{arg.rust_type}}{%if not loop.last%}, {%endif%}{%endfor%}) -> Result<{{method.return_value_rust_type}}, MethodResultCode> {
    println!("Handling {{method_name}}");
    {%-if method.return_value_type == 'struct'%}
    let rv = {{method.return_value_rust_type}} {
        {%for arg in method.return_value-%}
        {{arg.name}}: {{arg.get_random_example_value(lang="rust")}},
        {%endfor%}
    };
    Ok(rv)
    {%elif method.return_value_type is not false %}
    Ok({{method.return_value.get_random_example_value(lang="rust")}})
    {%else%}
    Ok(())
    {%-endif%}
}
{%endfor%}


#[tokio::main]
async fn main() {
    block_on(async {
        {%set broker = stinger.get_example_broker()%}
        let mut connection = MqttierClient::new("localhost", 1883, None).unwrap();
        let mut server = {{stinger.rust.server_struct_name}}::new(&mut connection).await;
        
        {%for prop_name, prop in stinger.properties.items()%}
        println!("Setting initial value for property '{{prop_name}}'");
        {%-if prop.arg_list | length == 1 %}
        server.set_{{prop_name | snake_case}}({{prop.arg_list[0].get_random_example_value(lang="rust")}}).await;
        {%-else%}{# many args in property #}
        let new_value = {{prop.rust_type}} {
            {%-for arg in prop.arg_list %}
                {{arg.name}}: {{arg.get_random_example_value(lang="rust")}},
            {%-endfor%}
        };
        server.set_{{prop_name | snake_case}}(new_value).await;
        {%endif%}
        {%endfor%}{# property initialization -#}
        {%-for method_name, method in stinger.methods.items()%}
        server.set_method_handler_for_{{method_name|snake_case}}({{method_name|snake_case}}_handler);
        {%endfor%}
        {%for sig_name, sig in stinger.signals.items()%}
        sleep(Duration::from_secs(1)).await;
        println!("Emitting signal '{{sig_name}}'");
        server.emit_{{sig_name|snake_case}}({%for arg in sig.arg_list%}{{arg.get_random_example_value(lang="rust")}}{%if not loop.last%}, {%endif%}{%endfor%}).await;
        {%endfor%}
        {%for prop_name, prop in stinger.properties.items()%}
        sleep(Duration::from_secs(1)).await;
        println!("Changing property '{{prop_name}}'");
        {%-if prop.arg_list | length == 1 %}
        server.set_{{prop_name | snake_case}}({{prop.arg_list[0].get_random_example_value(lang="rust", seed=3)}}).await;
        {%-else%}{# many args in property #}
        let new_value = {{prop.rust_type}} {
            {%-for arg in prop.arg_list %}
                {{arg.name}}: {{arg.get_random_example_value(lang="rust", seed=4)}},
            {%-endfor%}
        };
        server.set_{{prop_name | snake_case}}(new_value).await;
        {%endif%}
        {%endfor%}{# property initialization -#}
        let _server_loop_task = server.receive_loop().await;
    });
    // Ctrl-C to stop
}
