import paraview.modules.vtkRemotingApplication
from paraview.modules.vtkRemotingServerManager import vtkClientSession
from paraview.modules.vtkRemotingPythonAsyncCore import (
    vtkPythonObservableWrapperUtilities,
)

from parat.services.properties import PropertyManager


class PipelineBuilder(paraview.modules.vtkRemotingApplication.vtkPTSPipelineBuilder):
    """
    A thin Python Wrapper around vtkPTSPipelineBuilder.
    """

    def __init__(self, session):

        if not isinstance(session, vtkClientSession):
            raise TypeError(" 'session' argument is not of type vtkClientSession")

        super().SetSession(session)

    async def CreateSource(self, group, name, **kwargs):
        """Given a group and proxy name, create and return a proxy instance.
        The proxy is initialized and registered with the proxy manager.
        kwargs can be any property of the proxy.

        Example:

          sphere = await builder.CreateSource("sources","SphereSource",Radius=10,Center=[0,0,7])

        """
        source = await vtkPythonObservableWrapperUtilities.GetFuture(
            super().CreateSource(group, name)
        )
        if kwargs:
            pm = PropertyManager()
            pm.SetValues(source, **kwargs)

        return source

    async def CreateFilter(self, group, name, Input, **kwargs):
        """Given a group, proxy name and input proxy, create and return a proxy of a filter.
        The proxy is initialized and registered with the proxy manager.
        kwargs can be any property of the proxy.

        Example:

          sphere = await builder.CreateSource("sources","SphereSource")
          filter = await builder.CreateFilter("filters","ShrinkFilter",sphere, ShrinkFactor=0.3)

        """

        filter = await vtkPythonObservableWrapperUtilities.GetFuture(
            super().CreateFilter(group, name, Input)
        )
        if kwargs:
            pm = PropertyManager()
            pm.SetValues(filter, **kwargs)

        return filter

    async def CreateView(self, group, name, **kwargs):
        view = await vtkPythonObservableWrapperUtilities.GetFuture(
            super().CreateView(group, name)
        )

        if kwargs:
            pm = PropertyManager()
            pm.SetValues(view, **kwargs)

        return view

    async def CreateRepresentation(
        self, producer, outputPort, view, representationType, **kwargs
    ):
        representation = await vtkPythonObservableWrapperUtilities.GetFuture(
            super().CreateRepresentation(producer, outputPort, view, representationType)
        )

        if kwargs:
            pm = PropertyManager()
            pm.SetValues(representation, **kwargs)

        return representation

    async def DeleteProxy(self, proxy):
        try:
            status = await vtkPythonObservableWrapperUtilities.GetFuture(
                super().DeleteProxy(proxy)
            )
        except RuntimeError:
            import traceback

            traceback.print_exc()
            raise RuntimeError("error")

        return status
