use miden::protocol::active_note
use miden::protocol::output_note

# ERRORS
# =================================================================================================

# PASS_THROUGH script expects exactly 14 note storage items
const ERR_PASS_THROUGH_WRONG_NUMBER_OF_STORAGE_ITEMS="wrong number of storage items"

#! PASS_THROUGH script:
#! Creates a note consumable by pass-through, containing the same asset.
#!
#! Inputs:  []
#! Outputs: []
#!
#! Note storage is assumed to be as follows:
#! - ASSET_KEY
#! - ASSET_VALUE
#! - RECIPIENT
#! - [note_type, tag]
@note_script
pub proc main
    # drop note arguments
    dropw

    # store note storage into memory starting at address 0
    push.0 exec.active_note::get_storage
    # => [num_storage_items, storage_ptr]

    # make sure the number of storage items is 14
    eq.14 assert.err=ERR_PASS_THROUGH_WRONG_NUMBER_OF_STORAGE_ITEMS
    # => [storage_ptr]

    # Load in reverse order so after output_note::create we get [note_idx, ASSET_KEY, ASSET_VALUE]
    # load ASSET_VALUE (deepest on stack)
    drop
    padw mem_loadw_le.4
    # => [ASSET_VALUE]

    # load ASSET_KEY on top
    padw mem_loadw_le.0
    # => [ASSET_KEY, ASSET_VALUE]

    # load RECIPIENT on top
    padw mem_loadw_le.8
    # => [RECIPIENT, ASSET_KEY, ASSET_VALUE]

    # load note_type and tag from memory
    mem_load.12 mem_load.13
    # => [tag, note_type, RECIPIENT, ASSET_KEY, ASSET_VALUE]

    # create a note using storage
    # Inputs: [tag, note_type, RECIPIENT]
    exec.output_note::create
    # => [note_idx, ASSET_KEY, ASSET_VALUE]

    # rearrange stack for add_asset which expects [ASSET_KEY, ASSET_VALUE, note_idx]
    movdn.8
    # => [ASSET_KEY, ASSET_VALUE, note_idx]

    # add asset to the note
    exec.output_note::add_asset
    # => [...]

    # clean stack
    dropw dropw dropw dropw
    # => []
end
