"""
ex02_part2_deploy_plugin.py
---------------------

This is a simple example of how to use the ratio1 SDK.

In this example, we connect to the network, choose a node and
    deploy a plugin that will extract frames from a video stream.
"""

from ratio1 import Instance, Payload, Pipeline, Session


def instance_on_data(pipeline: Pipeline, data: Payload):
  # the images can be extracted from the Payload object
  # PIL needs to be installed for this to work
  images = data.get_images_as_PIL()
  if images is not None:
    if len(images) > 0 and images[0] is not None:
      images[0].save('frame.jpg')


if __name__ == '__main__':
  # create a session
  # the network credentials are read from the .env file automatically

  # NOTE: When working with SDK please use the nodes internal addresses. While the EVM address of the node
  #       is basically based on the same sk/pk it is in a different format and not directly usable with the SDK
  #       the internal node address is easily spoted as starting with 0xai_ and can be found 
  #       via `docker exec r1node get_node_info` or via the launcher UI

  session: Session = Session(encrypt_comms=True)

  session.wait_for_any_node()

  chosen_node = session.get_active_nodes()[0]

  # we have our node, let's deploy a plugin

  # first, we create a pipeline
  # we will use the video file data source, since we want to extract frames from a video
  pipeline: Pipeline = session.create_pipeline(
    node=chosen_node,
    name='first_deploy',
    data_source='VideoFile',
    config={
      'URL': "https://www.dropbox.com/scl/fi/8z2wpeelhav3k2dv8bb5p/Cars_3.mp4?rlkey=imv415rr3j1tx3zstpurlxkqb&dl=1"
    }
  )

  # next, we deploy a plugin instance
  # we will use the view scene plugin, which essentially generates payloads with frames from the video
  # to consume the payloads generated by the plugin, we need to specify a callback function
  instance: Instance = pipeline.create_plugin_instance(
    signature='VIEW_SCENE_01',
    instance_id='inst01',
    on_data=instance_on_data,
    # we can specify the configuration for the plugin instance as kwargs
    process_delay=3,
    # we can also specify if the payloads should be encrypted
    # if so, only the creator of this pipeline, in our case us, will be able to decrypt the payloads
    encrypt_payload=True,
  )

  pipeline.deploy()

  # Observation:
  #   next code is not mandatory - it is used to keep the session open and cleanup the resources
  #   due to the fact that this is a example/tutorial and maybe we dont want to keep the pipeline
  #   active after the session is closed we use close_pipelines=True
  #   in production, you would not need this code as the script can close 
  #   after the pipeline will be sent 
  session.wait(
    seconds=120,            # we wait the session for 60 seconds
    close_pipelines=True,   # we close the pipelines after the session
    close_session=True,     # we close the session after the session
  )
  session.P("Main thread exiting...")
