Definition: [
    "autonomous agent",
    {
        "init": "{
        // FOREVER CONSTANT
            $AA_NAME= "HOLLAA"; // Holder Of Linked List AA;
            $AA_OWNER = "O7NYCFUL5XIJTYE3O4MKGMGMTN6ATQAJ"; 
            $INSTRUCTIONS = "For every operation 'list_name = <list name>' is needed. To add an element at the end of the list use ', 'add = <item name>' and optionaly 'value = <item value>'. To remove 'remove = <item name>'. You can insert with 'insert = <item name>', 'after/before = <ref item name>' and optionaly 'value = <item value>'. When the list s empty, you can delete it with 'delete = true'. If you need to iterate you might find useful to be triggered back with the next or previous item, use 'get_next/get_previous = <actual item name>'.";
           
        // get info from state or input data
            $inputs = "For the moment I received: "||json_stringify(trigger.data)||json_stringify(trigger.output[[asset=base]]);
            $list_name = trigger.data.list_name otherwise bounce ("Need 'list = <list_name>'!"||$inputs);
            $list_owner = var[$list_name||"_owner"] otherwise trigger.address;
            $list_items_count = var[$list_name||"_items_count"] otherwise 0;
            
        // access checking
            $list_is_public = var[$list_name||"_is_public"] otherwise trigger.data.public;
            if (!$list_is_public) if (trigger.address != $list_owner)
                bounce ("You don't own this private list");
    }",
        "messages": {
            "cases": [
                {
                    "if": "{ !!trigger.data.add }",
                    "init": "{
                    // get the item and its key used for state var 
                        $item = trigger.data.add;       
                        $item_key = $list_name||"_"||$item;
                }",
                    "messages": [
                        {
                            "app": "state",
                            "state": "{
                            // update list properties
                                var[$list_name||"_owner"] = $list_owner;
                                var[$list_name||"_items_count"] = $list_items_count + 1;
                                var[$list_name||"_is_public"] = $list_is_public;
                            // update previously last item
                                $last_item = var[$list_name||"_last_item"];  
                                $last_item_key = $list_name||"_"||$last_item;
                                if (!!$last_item) var[$last_item_key||"_next_item"] = $item;
                            // if this is the first item we have to set the first_item state var
                                if (var[$list_name||"_items_count"] == 1 ) var[$list_name||"_first_item"] = $item;
                            // add new item at the end of the linked list
                                var[$list_name||"_last_item"] = $item;
                                var[$item_key] = trigger.data.value otherwise true;
                                var[$item_key||"_previous_item"] = $last_item;
                                var[$item_key||"_next_item"] = false;
                            response['message']= $item||" added ^^.";
                        }"
                        }
                    ]
                },
                {
                    "if": "{ !!trigger.data.remove }",
                    "init": "{
                    // get the item and its key used for state var 
                        $item = trigger.data.remove;      
                        $item_key = $list_name||"_"||$item;
                    // check that the list exist
                        if (!(var[$list_name||"_owner"]))
                            bounce ("'"||$list_name||"' did not exist !");
                    // check if item exist       
                        if (!(var[$item_key]))
                            bounce ($item||" did not exist !");
                    // get the previous items
                        $previous_item = var[$item_key||"_previous_item"];  
                        $previous_item_key = $list_name||"_"||$previous_item;
                    // get the next items
                        $next_item = var[$item_key||"_next_item"];          
                        $next_item_key = $list_name||"_"||$next_item;
                }",
                    "messages": [
                        {
                            "app": "state",
                            "state": "{
                            // update list state
                                var[$list_name||"_items_count"] = $list_items_count - 1;
                                
                            // update link in previous item
                                var[$previous_item_key||"_next_item"] = $next_item;
                            // update link in next item
                                var[$next_item_key||"_previous_item"] = $previous_item;
                            // remove item
                                var[$item_key] = false;
                                var[$item_key||"_previous_item"] = false;
                                var[$item_key||"_next_item"] = false;
                            response['message']= trigger.data.remove||" removed ^^.";
                        }"
                        }
                    ]
                },
                {
                    "if": "{ !!trigger.data.insert }",
                    "init": "{
                    // check that the list exist
                        if (!(var[$list_name||"_owner"]))
                            bounce ("'"||$list_name||"' did not exist !");
                    // get the item and its key used for state var 
                        $item = trigger.data.insert;
                        $item_key = $list_name||"_"||$item;
                    // identify previous and next items
                        if (!!trigger.data.after)
                        {
                            $previous_item = trigger.data.after;
                            $previous_item_key = $list_name||"_"||$previous_item;
                            if (!var[$previous_item_key]) bounce ($previous_item||" do NOT exist !");
                            $next_item = var[$previous_item_key||"_next_item"];
                        }
                        else
                        {
                            if (!!trigger.data.before)
                            {
                                $next_item = trigger.data.before;
                                $next_item_key = $list_name||"_"||$next_item;
                                if (!var[$next_item_key]) bounce ($next_item||" do NOT exist !");
                                $previous_item_key = var[$next_item_key||"_previous_item"];
                            }
                            else
                            {
                                bounce ("Please, specify 'after' or 'before' = <existing item>");
                            }
                        }
                }",
                    "messages": [
                        {
                            "app": "state",
                            "state": "{
                            // update list state
                                var[$list_name||"_items_count"] = $list_items_count + 1;
                            // update previous item link
                                if (!!$previous_item_key)
                                    var[$previous_item_key||"_next_item"] = $item;
                                else
                                    var[$list_name||"_first_item"] = $item;
                            // update next item link
                                if (!!$next_item_key)
                                    var[$next_item_key||"_previous_item"] = $item;
                                else
                                    var[$list_name||"_last_item"] = $item;
                            // add new item 
                                var[$item_key] = trigger.data.value otherwise true;
                                var[$item_key||"_previous_item"] = $previous_item;
                                var[$item_key||"_next_item"] = $next_item;
                            response['message'] = $item||" added ^^.";
                        }"
                        }
                    ]
                },
                {
                    "if": "{ trigger.data.delete }",
                    "init": "{
                    // check if list exist
                        if (!var[$list_name||"_owner"]) 
                            bounce ("'"||$i.list_name||"' did not exist at the first place!");
                    // check that the list is empty so taht we can delete it without leaving anything in AA state var
                        if (var[$list_name||"_items_count"] > 0) 
                            bounce ("List must be empty to be deleted, use 'remove_last_item' as much as needed");
                }",
                    "messages": [
                        {
                            "app": "state",
                            "state": "{
                            var[$list_name||"_owner"] = false;
                            var[$list_name||"_items_count"] = false;
                            var[$list_name||"_is_public"] = false;
                            response['message']= $list_name||" delete ^^.";
                        }"
                        }
                    ]
                },
                {
                    "if": "{ !!trigger.data.get_next }",
                    "init": "{
                    // check that the list exist
                        if (!(var[$list_name||"_owner"]))
                            bounce ("'"||$list_name||"' did not exist !");
                    // get next item from specify one or very first one.
                        $next_from_item = trigger.data.get_next;
                        $next_from_item_key = $list_name||"_"||$next_from_item;
                        // if the specify item from which starting exist
                            $next_item = !!var[$next_from_item_key] ?     
                                // return the next item of the list 
                                var[$next_from_item_key||"_next_item"] otherwise bounce ("Was last item!"):
                                // or start from the first item of the list
                                var[$list_name||"_first_item"];             
                }",
                    "messages": [
                        {
                            "app": "data",
                            "payload": {
                                "item_name": "{ $next_item }",
                                "item_value": "{ var[$list_name||$next_item] }",
                                "token": "{ trigger.data.token }"
                            }
                        },
                        {
                            "app": "payment",
                            "payload": {
                                "outputs": [
                                    {
                                        "address": "{ trigger.address }",
                                        "amount": "{4}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            response['message']= $next_item||" sent ^^.";
                        }"
                        }
                    ]
                },
                {
                    "if": "{ !!trigger.data.get_previous }",
                    "init": "{
                    // check that the list exist
                        if (!(var[$list_name||"_owner"]))
                            bounce ("'"||$list_name||"' did not exist !");
                    // get previous item from specify one or very last one.
                        $previous_from_item = trigger.data.get_previous;
                        $previous_from_item_key = $list_name||"_"||$previous_from_item;
                        // if the specify item from which starting exist
                            $previous_item = !!var[$previous_from_item_key] ?       
                                // return the next item of the list
                                var[$previous_from_item_key||"_previous_item"] otherwise bounce ("Was first item!") :  
                                // or start from the last item of the list  
                                var[$list_name||"_last_item"];
                }",
                    "messages": [
                        {
                            "app": "data",
                            "payload": {
                                "item_name": "{ $previous_item }",
                                "item_value": "{ var[$list_name||$previous_item] }",
                                "token": "{ trigger.data.token }"
                            }
                        },
                        {
                            "app": "payment",
                            "payload": {
                                "outputs": [
                                    {
                                        "address": "{ trigger.address }",
                                        "amount": "{4}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            response['message']= $previous_item||" sent ^^.";
                        }"
                        }
                    ]
                },
                {
                    "messages": [
                        {
                            "app": "state",
                            "state": "{ 
                    bounce ($INSTRUCTIONS||$inputs);
                }"
                        }
                    ]
                }
            ]
        }
    }
]