[
    "autonomous agent",
    {
        "init": "{
        $owner = 'JBGMJI7XSKLKNHZF26BUBWHVUZSDV3P5';
        $fee = 1000;
        $addr = trigger.address;
        $bounce_fee = 10000;
        $base_inp = trigger.output[[asset=base]];
        $base_key = 'base_' || trigger.address;
        if($base_inp <= 0)
            bounce("no inputs detected");
        
        if(trigger.output[[asset!=base]].asset != 'none')
            $asset = trigger.output[[asset!=base]].asset;
        if($asset){
            if($asset == 'ambiguous'){
                bounce("only 1 asset per tx");
            }
            if(trigger.output[[asset!=base]] ==0)
                bounce("zero asset tx");
            $asset_inp = trigger.output[[asset!=base]];
        }
        if(var['asset']){
            $asset_key = var['asset']||'_'||trigger.address;
            if($asset and var['asset'] != $asset)
                bounce("not a previously defined asset");
        }
        else{
            if($asset){
                $asset_key = $asset||'_'||trigger.address;
            }
            else{
                if(!trigger.data.asset)
                    bounce("a asset must be defined first time");
            }
        }
        
        $ratio = 1000;//bytes per 1 asset
        $max_b_to_exchange = var['total'];
        $max_a_to_exchange = var['total_asset'];
        $base_inp_in_asset = $base_inp/$ratio;
        $asset_inp_in_bytes = $asset_inp*$ratio;
        if($asset){
            if($max_b_to_exchange and $max_b_to_exchange != 0){
                //exchange
                if($asset_inp_in_bytes > $max_b_to_exchange){
                    //partial exchange till empty,return rest
                    $byte_amount = $max_b_to_exchange;
                    $asset_amount = ($asset_inp_in_bytes - $max_b_to_exchange)/$ratio;
                }
                else{
                    //full exchange until empty,return bfees
                    $byte_amount = $asset_inp_in_bytes;
                    $asset_amount = 0;
                }
            }
            else{
                $deposit = true;
            }
        }
        else{
            if($max_a_to_exchange and $max_a_to_exchange != 0 and !trigger.data.cancel){
                //exchange
                if($base_inp_in_asset > $max_a_to_exchange){
                    //partial exchange till empty,deposit rest
                    $asset_amount = $max_a_to_exchange;
                    $byte_amount = ($base_inp_in_asset - $max_a_to_exchange)*$ratio;
                }
                else{
                    //full exchange until empty
                    $asset_amount =  $base_inp_in_asset ;
                    $byte_amount = 0;
                }
            }
            else{
                $deposit = true;
            }
        }
    }",
        "messages": {
            "cases": [
                {
                    "if": "{
                        
                        $asset and $byte_amount and !var[$base_key]
                    }",
                    "messages": [
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "base",
                                "outputs": [
                                    {
                                        "address": "{$addr}",
                                        "amount": "{$byte_amount-$fee}"
                                    }
                                ]
                            }
                        },
                        {
                            "if": "{$asset_amount > 0}",
                            "app": "payment",
                            "payload": {
                                "asset": "{var['asset']}",
                                "outputs": [
                                    {
                                        "address": "{$addr}",
                                        "amount": "{$asset_amount}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            var['total_asset'] += $asset_amount;
                            var['total'] -= $byte_amount;
                            response['message'] = 'exchanged asset x bytes';
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                        !$asset and $asset_amount and !var[$asset_key]
                    }",
                    "messages": [
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "{var['asset']}",
                                "outputs": [
                                    {
                                        "address": "{$addr}",
                                        "amount": "{$asset_amount}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            var['total_asset'] -= $asset_amount;
                            if( ($byte_amount-$fee) <= 0){
                                response['message'] = 'exchanged bytes x asset';
                            }
                            else{
                                var['total'] += $byte_amount-$fee;
                                response['message'] = 'exchanged bytes x asset'||', deposited '||($byte_amount-$fee)|| ' bytes';
                            }
                                
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                        var['total'] and var[$asset_key] and var['total'] > 0 and var[$asset_key] > 0
                    }",
                    "messages": [
                        {
                            "init": "{
                            $max_to_retire = var[$asset_key]*$ratio;
                            if(var['total'] <= $max_to_retire){
                                $retire_amount = var['total'];
                            }
                            else{
                                $retire_amount = $max_to_retire;
                            }
                        }",
                            "app": "payment",
                            "payload": {
                                "asset": "base",
                                "outputs": [
                                    {
                                        "address": "{$addr}",
                                        "amount": "{$retire_amount+$base_inp}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            var['total'] -= $retire_amount;
                            $ret_ass = $retire_amount/$ratio;
                            var['total_asset'] -= $ret_ass;
                            var[$asset_key] -= $ret_ass;
                            response['message'] = 'retired exchanged amount (bytes)';
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                        var['total_asset'] and var[$base_key] and var['total_asset'] > 0 and var[$base_key] > 0
                    }",
                    "messages": [
                        {
                            "init": "{
                            $max_to_retire = var[$base_key]/$ratio;
                            if(var['total_asset'] <= $max_to_retire){
                                $retire_amount = var['total_asset'];
                            }
                            else{
                                $retire_amount = $max_to_retire;
                            }
                        }",
                            "app": "payment",
                            "payload": {
                                "asset": "base",
                                "outputs": [
                                    {
                                        "address": "{$addr}",
                                        "amount": "{$base_inp}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "{var['asset']}",
                                "outputs": [
                                    {
                                        "address": "{$addr}",
                                        "amount": "{$retire_amount}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            var['total_asset'] -= $retire_amount;
                            $ret_bas = $retire_amount*$ratio;
                            var['total'] -= $ret_bas;
                            var[$base_key] -= $ret_bas;
                            response['message'] = 'retired exchanged amount (asset)';
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                        trigger.data.cancel and var['total_asset'] and var[$asset_key] and var['total_asset'] > 0 and var[$asset_key] > 0
                    }",
                    "init": "{
                        if(var['total_asset'] <= var[$asset_key]){
                            $retire_amount = round(var['total_asset']);
                        }
                        else{
                            $retire_amount = round(var[$asset_key]);
                        }
                    }",
                    "messages": [
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "base",
                                "outputs": [
                                    {
                                        "address": "{$addr}",
                                        "amount": "{round($base_inp-(2*$fee))}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "{var['asset']}",
                                "outputs": [
                                    {
                                        "address": "{$addr}",
                                        "amount": "{$retire_amount}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            var['total_asset'] -= $retire_amount;
                            var[$asset_key] -= $retire_amount;
                            response['message'] = 'canceled order (asset)';
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                        trigger.data.cancel and var['total'] and var[$base_key] and var['total'] > 0 and var[$base_key] > 0
                    }",
                    "init": "{
                        if(var['total'] <= var[$base_key]){
                            $retire_amount = var['total'];
                        }
                        else{
                            $retire_amount = var[$base_key];
                        }
                }",
                    "messages": [
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "base",
                                "outputs": [
                                    {
                                        "address": "{$addr}",
                                        "amount": "{$retire_amount+$base_inp-(2*$fee)}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            var['total'] -= $retire_amount;
                            var[$base_key] -= $retire_amount;
                            response['message'] = 'canceled order (bytes)';
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                        if(!$deposit){
                            bounce("f");
                        }
                        $deposit
                    }",
                    "messages": [
                        {
                            "if": "{$asset}",
                            "app": "payment",
                            "payload": {
                                "asset": "base",
                                "outputs": [
                                    {
                                        "address": "{$addr}",
                                        "amount": "{$base_inp-$fee}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            if(!var['asset']){
                                var['total_asset'] = 0;
                                var['total'] = 0;
                                if($asset)
                                    var['asset'] = $asset;
                                else
                                    var['asset'] = trigger.data.asset;
                            }
                            if($asset){
                                var['total_asset'] += $asset_inp;
                                var[$asset_key] += $asset_inp;
                                response['message'] = 'deposited asset';
                            }
                            else{
                                var['total'] += $base_inp;
                                var[$base_key] += $base_inp;
                                response['message'] = 'deposited bytes';
                            }
                            
                        }"
                        }
                    ]
                }
            ]
        }
    }
]