# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/plugin.pluginbase.ipynb (unless otherwise specified).

__all__ = ['POD_FULL_ADDRESS_ENV', 'POD_TARGET_ITEM_ENV', 'POD_OWNER_KEY_ENV', 'POD_AUTH_JSON_ENV', 'PluginBase',
           'PluginRun', 'MyItem', 'MyPlugin', 'run_plugin_from_run_id', 'register_base_classes', 'run_plugin',
           'StartPlugin']

# Cell
from ..data.schema import *
from ..pod.client import PodClient, DEFAULT_POD_ADDRESS
from ..imports import *
from os import environ
from abc import ABCMeta
import abc
import json

# Cell
POD_FULL_ADDRESS_ENV        = 'POD_FULL_ADDRESS'
POD_TARGET_ITEM_ENV         = 'POD_TARGET_ITEM'
POD_OWNER_KEY_ENV           = 'POD_OWNER'
POD_AUTH_JSON_ENV           = 'POD_AUTH_JSON'

# Cell
# hide
class PluginBase(Item, metaclass=ABCMeta):
    """Base class for plugins"""
    properties = Item.properties + ["name", "repository", "icon", "data_query", "bundleImage",
                                    "runDestination", "pluginClass", "pluginPackage"]
    edges = Item.edges + ["PluginRun"]

    def __init__(self, name=None, repository=None, icon=None, query=None, bundleImage=None, runDestination=None,
                 pluginClass=None, indexerRun=None, **kwargs):
        if pluginClass is None: pluginClass=self.__class__.__name__
        self.pluginPackage=None
        super().__init__(**kwargs)
        self.name = name
        self.repository = repository
        self.icon = icon
        self.query = query
        self.bundleImage = bundleImage
        self.runDestination = runDestination
        self.pluginClass = pluginClass
        self.indexerRun = indexerRun if indexerRun is not None else []

    @abc.abstractmethod
    def run(self):
        raise NotImplementedError()

    @abc.abstractmethod
    def add_to_schema(self):
        raise NotImplementedError()

# Cell
# hide
class PluginRun(Item):
    properties = Item.properties
    edges = Item.edges + ["plugin"]

    def __init__(self, plugin=None, **kwargs):
        super().__init__(**kwargs)
        self.plugin=plugin if plugin is not None else []

# Cell
# hide
class MyItem(Item):
    properties = Item.properties + ["name", "age"]
    edges = Item.edges
    def __init__(self, name=None, age=None, **kwargs):
        super().__init__(**kwargs)
        self.name = name
        self.age = age

class MyPlugin(PluginBase):
    """"""
    properties = PluginBase.properties
    edges= PluginBase.edges

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.pluginPackage="pymemri.plugin.pluginbase"

    def run(self, run, client):
        print("running")
        client.create(MyItem("some person", 20))

    def add_to_schema(self, client):
        client.add_to_schema(MyItem("my name", 10))

# Cell
# export
def run_plugin_from_run_id(run_id, client):
    run = client.get(run_id)
    plugins = run.plugin
    if len(plugins) == 0:
        raise ValueError(f"plugin run {run_id} has no plugin attached to it. Make sure there is a 'plugin' \
                           edge from your run to the actual plugin object.")
    if len(plugins) > 1:
        raise ValueError("Too many plugins attached to run")
    plugin = plugins[0]
    plugin.add_to_schema(client)
    plugin.run(run, client)

# Cell
# hide
def register_base_classes(client):
    try:
        assert client.add_to_schema(PluginRun())
    except Exception as e:
        raise ValueError("Could not add base schema")

# Cell
def _run_plugin(client, plugin_run_id=None, verbose=False):
    """Runs an plugin, you can either provide the run settings as parameters to this function (for local testing)
    or via environment variables (this is how the pod communicates with plugins)."""
    register_base_classes(client)
    run_plugin_from_run_id(plugin_run_id, client)


# Cell
# hide
def _parse_env(env):
    try:
        pod_full_address = env.get(POD_FULL_ADDRESS_ENV, DEFAULT_POD_ADDRESS)
        plugin_run_json  = json.loads(str(env[POD_TARGET_ITEM_ENV]))
        print(plugin_run_json)
        plugin_run_id    = plugin_run_json["id"]
        owner_key        = env.get(POD_OWNER_KEY_ENV)
        pod_auth_json    = json.loads(str(env.get(POD_AUTH_JSON_ENV)))
#         database_key = pod_service_payload[DATABASE_KEY_ENV]
#         owner_key    = pod_service_payload[OWNER_KEY_ENV]
        return pod_full_address, plugin_run_id, pod_auth_json, owner_key
    except KeyError as e:
        raise Exception('Missing parameter: {}'.format(e)) from None


# Cell
from fastscript import *
import os

@call_parse
def run_plugin(pod_full_address:Param("The pod full address", str)=None,
               plugin_run_id:Param("Run id of the plugin to be executed", str)=None,
               database_key:Param("Database key of the pod", str)=None,
               owner_key:Param("Owner key of the pod", str)=None,
               from_pod:Param("Run by calling the pod", bool)=False,
               container:Param("Pod container to run frod", str)=None):

    env = os.environ
    params = [pod_full_address, plugin_run_id, database_key, owner_key]

    if all([p is None for p in params]):
        print("Reading `run_plugin()` parameters from environment variables")
        pod_full_address, plugin_run_id, pod_auth_json, owner_key = _parse_env(env)
        database_key=None
    else:
        print("Used arguments passed to `run_plugin()` (ignoring environment)")
        pod_auth_json=None
        if (None in params):
            raise ValueError(f"Defined some params to run indexer, but not all. Missing \
                             {[p for p in params if p is None]}")
    client = PodClient(url=pod_full_address, database_key=database_key, owner_key=owner_key,
                       auth_json=pod_auth_json)
    for name, val in [("pod_full_address", pod_full_address), ("plugin_run_id", plugin_run_id),
                      ("owner_key", owner_key), ("auth_json", pod_auth_json)]:
        print(f"{name}={val}")
    print()
    if from_pod:
        print(f"calling the `create` api on {pod_full_address} to make your Pod start "
              f"a plugin with id {plugin_run_id}.")
        print(f"*Check the pod log/console for debug output.*")
        client.start_plugin("pymemri", plugin_run_id)
    else:
        _run_plugin(client=client, plugin_run_id=plugin_run_id)

# Cell
# hide
class StartPlugin(Item):
    properties = Item.properties + ["container", "targetItemId"]
    edges = Item.edges
    def __init__(self, container=None, targetItemId=None, **kwargs):
        super().__init__(**kwargs)
        self.container = container
        self.targetItemId = targetItemId