#include "rosa/app/Application.hpp"

std::unique_ptr<Application> A = Application::create("App");
// sensor
A->createSensor<Input, output>(name,
                               // lambda function
                               [](std::pair<input, bool> I) -> void {
                                 // automatically pushes its value to the
                                 // connected agent
                               });

// ---------------------------------------------------------------------------
// communication with 1 other agent
// ---------------------------------------------------------------------------
// Handlerfunctions have to be the corresponding std::functions

// singe input singe output
A->createAgent(Name,
               Handlerfunction(
                   // lambda function
                   [](std::pair<InputType, bool> I) -> optional<ResultType> {
                     //...
                     // return {value};
                   }));

// multi input single output
A->createAgent(Name, Handlerfunction(
                         // lambda function
                         [](std::pair<AppTuple<InputType1, InputType2>, bool> I)
                             -> optional<AppTuple<ResultType>> {
                           //...
                           // AppTuple<ResultType> output(value);
                           // return {output};
                         }));

// single input multi output
A->createAgent(Name, Handlerfunction(
                         // lambda function
                         [](std::pair<AppTuple<InputType>, bool> I)
                             -> optional<AppTuple<ResultType1, ResultType2>> {
                           //...
                           // AppTuple<ResultType1, ResultType2>
                           // output(value1,value2);
                           // return {output};
                         }));

// multi in/out and handles results from master
A->createAgent(
    Name,
    // Master-input handler.
    MasterHandlerfunction(
        // lambda function
        [](std::pair<AppTuple<feedbackType>, bool> I)
            -> void { // you can again return something to the master but i
                      // don't know at the moment the changes that would cause
                      //
                      //..
        }),
    // input handler.
    Handlerfunction(
        // lambda function
        [](std::pair<AppTuple<InputType1, InputType2>, bool> I)
            -> optional<AppTuple<ResultType1, ResultType2>> {
          //...
          // AppTuple<ResultType1, ResultType2>
          // output(value1,value2);
          // return {output};
        }));

// ---------------------------------------------------------------------------
// communication with n other agent
// ---------------------------------------------------------------------------

// I don't know how it reacts if input 1 is a AppTuple and input 2 is just a
// value I'm just using all with AppTuples
A->createAgent(
    Name, Handlerfunction(
              // lambda function
              [](std::pair<AppTuples<SlaveOutputs1...>, bool> I0,
                 std::pair<AppTuples<SlaveOutputs2...>, bool> I1,
                 std::pair<AppTuples<SlaveOutputs3...>, bool> I2,
                 ...) -> std::tuple<Optional<AppTuple<give_to_master>>,
                                    Optional<AppTuple<give_to_slave1>>,
                                    Optional<AppTuple<give_to_slave2>>,
                                    Optional<AppTuple<give_to_slave3>>, ...>;
              {
                  // ...
                  // return {{for_master}, {for_slave_1}, {for_slave_1},
                  // {for_slave_1}};
              }));
