##################################################################################
#  SENSIML CONFIDENTIAL                                                          #
#                                                                                #
#  Copyright (c) 2017  SensiML Corporation.                                      #
#                                                                                #
#  The source code contained or  described  herein and all documents related     #
#  to the  source  code ("Material")  are  owned by SensiML Corporation or its   #
#  suppliers or licensors. Title to the Material remains with SensiML Corpora-   #
#  tion  or  its  suppliers  and  licensors. The Material may contain trade      #
#  secrets and proprietary and confidential information of SensiML Corporation   #
#  and its suppliers and licensors, and is protected by worldwide copyright      #
#  and trade secret laws and treaty provisions. No part of the Material may      #
#  be used,  copied,  reproduced,  modified,  published,  uploaded,  posted,     #
#  transmitted, distributed,  or disclosed in any way without SensiML's prior    #
#  express written permission.                                                   #
#                                                                                #
#  No license under any patent, copyright,trade secret or other intellectual     #
#  property  right  is  granted  to  or  conferred upon you by disclosure or     #
#  delivery of the Materials, either expressly, by implication,  inducement,     #
#  estoppel or otherwise.Any license under such intellectual property rights     #
#  must be express and approved by SensiML in writing.                           #
#                                                                                #
#  Unless otherwise agreed by SensiML in writing, you may not remove or alter    #
#  this notice or any other notice embedded in Materials by SensiML or SensiML's #
#  suppliers or licensors in any way.                                            #
#                                                                                #
##################################################################################

from six import string_types
from sensiml.datamanager.pipeline import PipelineStep


class FunctionCall(PipelineStep):
    """The base class for a function call.

    Child classes have their own additional properties and overwrite this docstring."""

    def __init__(self, name, function_type='transform'):
        super(FunctionCall, self).__init__(name=name, step_type='FunctionCall')
        self._type = function_type

    @property
    def outputs(self):
        return self._outputs

    @outputs.setter
    def outputs(self, outputs):
        self._outputs = outputs

    def _check_inputs(self, output_vars=[]):
        """Compares the list of inputs with the given output_vars list

            Args:
                output_vars (list[str]): the current set of output variables

            Returns:
                unmatched_inputs (list[str]): unmatched inputs or an empty list if all inputs are matched
        """
        unmatched_inputs = []
        for param in [getattr(self, input['name']) for input in self._input_contract]:
            if isinstance(param, string_types) and param.find('temp.') > -1 and not param in output_vars:
                unmatched_inputs.append(param)
        return unmatched_inputs

    def _public_properties(self):
        """Returns the object's public properties, i.e. those that do not start with _"""
        return (name for name in dir(self) if not name.startswith('_'))

    def _to_dict(self):
        prop_dict = {}
        prop_dict['name'] = self._name
        prop_dict['type'] = self._type
        prop_dict['feature_table'] = self._feature_table
        prop_dict['inputs'] = {}
        for prop in [input['name'] for input in self._input_contract if not input.get('handle_by_set', False)]:
            if prop != 'outputs':
                prop_dict['inputs'][prop] = getattr(self, prop)
        prop_dict['outputs'] = getattr(self, 'outputs')
        return prop_dict
