from 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
