#!/usr/bin/env python
"""Provides AssetVista datatypes definitions for creating logic Conditions and SubConditions.

This module defines the types for avlogic Conditions and SubConditions
"""

from typing import Callable, Dict

from .avlayerTypes import *
from .edgeniusTypes import EdgeniusOutput, EdgeniusOutputList

__author__ = "Tiago Prata"
__copyright__ = "Copyright 2022, ABB Automacao Ltda (Brazil)"
__credits__ = ["ABB Automacao Ltda", "Tiago Prata"]
__license__ = "Copyright"
__version__ = "1.0.1"
__maintainer__ = "AssetVista Team"
__email__ = "BR-assetvista@abb.com"
__status__ = "Development (do not use in production)"

# TODO: Add comments to classes and functions
# TODO: Create test script

class SubCondition:
    def __init__(self, variables, output_value: int, disable_if_any_variable_is_out_of_range: bool = True):
        self.variables = variables
        self.output_value = output_value
        self.disable_if_any_variable_is_out_of_range = disable_if_any_variable_is_out_of_range
        self.function: Callable[..., bool] = None
        self.enabled = self._is_subcond_enabled()


    def _is_subcond_enabled(self):
        enabled = True
        for variable in self.variables:
            if isinstance(variable, (AvtypeNumeric, AvtypeInteger, AvtypeBoolean, AvtypeString)):
                if (not variable.in_use) or variable.out_of_range:
                    enabled = False
                    break
        
        return enabled


class Condition:
    def __init__(self, outputRecords):
        self.subconditions: Dict[int, SubCondition] = {}
        self.active_subcond = self._get_active_subcond_index()
        self.outputRecords = outputRecords

    
    def _get_active_subcond_index(self):
        index = 0
        for key, subcond in self.subconditions.items():
            if subcond.function != None:
                if subcond.enabled and subcond.function():
                    if (index==0) or (key<index):
                        index = key

        return index


    def output_value(self) -> int:
        active_index = self._get_active_subcond_index()
        if active_index == 0: return 0

        return self.subconditions[active_index].output_value


    def are_all_subconditions_disabled(self) -> bool:
        counter = 0
        all_subconditions_disabled = False

        for _, subcond in self.subconditions.items():
            if not subcond.enabled:
                counter += 1

        if len(self.subconditions) == counter:
            all_subconditions_disabled = True

        return all_subconditions_disabled

    
    def conv_outputRecords_to_list_of_edgeniusOutput(self):
        output_list = []
        for item in vars(self.outputRecords):
            output_name = item
            output_value = getattr(self.outputRecords, item)

            output_list.append(EdgeniusOutput(output_name, output_value))
        
        return output_list

    
    def get_edgenius_outputs(self):
        condition_status = EdgeniusOutput('ConditionStatus', self.output_value())
        enabled = EdgeniusOutput('Enabled', not self.are_all_subconditions_disabled())

        outputRecords_list = self.conv_outputRecords_to_list_of_edgeniusOutput()

        outputs = EdgeniusOutputList([condition_status, enabled] + outputRecords_list)

        return outputs.get_all_outputs()