from src.parser.parser_base import ParserBase

class FeatureEngineeringParser(ParserBase):

    def parse(self, data: list):
        return self._parse_feature_engineering_configs(data)
        
    def _parse_feature_engineering_configs(self, data: list):
        if(not data): return
        
        configs = []
        columns_set_alias = []
        for inputs in data:
            input = self._try_get(inputs, 'input')
            
            # columns
            columns_set, columns_alias = self._get_dataframe(self._try_get(input, 'columns'))
            columns_set_alias = columns_alias + columns_set_alias
            
            # features
            word_embedding, keyboard_smash = self._get_features_details(self._try_get(input, 'features'))
            data_lang, dimensions = self._get_word_embedding_config(word_embedding, columns_set_alias)
            
            # Enabled features
            enabled_features = keyboard_smash
            if(not dimensions): enabled_features['word_embedding'] = False
            else: enabled_features['word_embedding'] = True
            
            configs.append({ 
                'columns_alias': columns_alias, 
                'columns_set': columns_set, 
                'data_lang': data_lang, 
                'dimensions': dimensions, 
                'enabled_features': enabled_features
            })
            
        return configs, columns_set_alias
            
    def _get_dataframe(self, columns: dict):
        if(not columns): return 
        
        columns_alias = []
        
        for column in columns:
            for key in column.keys():
                columns_alias.append(key)
                
        return columns, columns_alias

    def _get_features_details(self, features: dict):
        if(not features): return
        
        word_embedding = self._try_get(features, 'word_embedding')
        if (word_embedding == 'off'): word_embedding = False
        
        keyboard_smash = self._get_keyboard_smash_config(features)
        
        return word_embedding, keyboard_smash
    
    def _get_word_embedding_config(self, feature: dict, columns_alias: list):
        if(not feature): return 'es', None
        
        data_lang = self._get(feature, 'data_lang', 'es')
        if ('data_lang' in feature): del feature['data_lang']
        
        dimensions = {}
        dimensions_default_value = 25
        for key, item in feature.items():
            if(not(key in columns_alias)): 
                error_msg = f'Label {key} not match'
                raise ValueError(error_msg)
            
            dimensions[key] = self._get(item, 'dimensions', dimensions_default_value)
            
        for name in columns_alias:
            if(not(name in dimensions)): dimensions[name] = dimensions_default_value
        
        return data_lang, dimensions

    def _get_keyboard_smash_config(self, features: dict):
        keyboard_smash_default_value = {
            'ksmash_sequence_vowels': True,
            'ksmash_sequence_consonants': True,
            'ksmash_sequence_special_characters': True,
            'ksmash_numbers': True,
            'ksmash_char_frequence': True
        }
        
        keyboard_smash = self._get(features, 'keyboard_smash', keyboard_smash_default_value)
        if (keyboard_smash == keyboard_smash_default_value): return keyboard_smash
        
        for key in keyboard_smash.keys():
            if(key in keyboard_smash_default_value and keyboard_smash[key] == 'off'):
                keyboard_smash_default_value[key] = False
        
        return keyboard_smash_default_value        
