from manifest_edit.plugin.mpd import ManifestIteratorPlugin
from manifest_edit.context import Context
import re
from schema import Schema, Optional


class Plugin(ManifestIteratorPlugin):
    """
    label add plugin.

    The purpose of this plugin is to add a label or a group label to a
    representation or an adaptation set.

    Users must provide at least the label text using the "data" field.
    As per standard "id" is optional and defaults to 0 and "lang" is optional.

    """

    _name = __name__

    _keys = ["label", "groupLabel"]

    # This is just the specific ["how" config] for this plugin
    def schema(self):
        return Schema(
            {
                Optional(self._keys[0], default=[]): [
                    {
                        Optional("id", default=".*"): str,
                        Optional("lang", default=".*"): str,
                        Optional("data", default=".*"): str,
                    }
                ],
                Optional(self._keys[1], default=[]): [
                    {
                        Optional("id", default=".*"): str,
                        Optional("lang", default=".*"): str,
                        Optional("data", default=".*"): str,
                    }
                ],
            }
        )

    def _removeLabel(self, attribute_name, label_config, element):
        # Iterate over labels and see if they match with the regular
        # expressions provided by the user
        label_list = getattr(element, attribute_name)
        for label_to_remove in label_config:
            id_regex = re.compile(label_to_remove["id"])
            lang_regex = re.compile(label_to_remove["lang"])
            data_regex = re.compile(label_to_remove["data"])
            for label in label_list:
                if (
                    id_regex.search(str(label.id))
                    and lang_regex.search(label.lang)
                    and data_regex.search(label.data)
                ):
                    label_list.remove(label)

    def _removeLabelOrGroupLabel(self, manifest, storage):
        for label_config, element in self.config(manifest, storage):
            if label_config["label"]:
                self._removeLabel(
                    attribute_name="labels",
                    label_config=label_config["label"],
                    element=element,
                )
            if label_config["groupLabel"]:
                self._removeLabel(
                    attribute_name="groupLabels",
                    label_config=label_config["groupLabel"],
                    element=element,
                )

    def process(self, manifest, storage):
        self._removeLabelOrGroupLabel(manifest, storage)
