"""Filter used to select the first preferred output format available,
excluding interactive widget format if the widget state is not available.

The filter contained in the file allows the converter templates to select
the output format that is most valuable to the active export format.  The
value of the different formats is set via
NbConvertBase.display_data_priority
"""
# -----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# Classes and functions
# -----------------------------------------------------------------------------

import os
from warnings import warn

from nbconvert.utils.base import NbConvertBase

__all__ = ["WidgetsDataTypeFilter"]


WIDGET_VIEW_MIMETYPE = "application/vnd.jupyter.widget-view+json"
WIDGET_STATE_MIMETYPE = "application/vnd.jupyter.widget-state+json"


class WidgetsDataTypeFilter(NbConvertBase):
    """Returns the preferred display format, excluding the widget output if
    there is no widget state available"""

    def __init__(self, notebook_metadata=None, resources=None, **kwargs):
        """Initialize the filter."""
        self.metadata = notebook_metadata
        self.notebook_path = ""
        if resources is not None:
            name = resources.get("metadata", {}).get("name", "")
            path = resources.get("metadata", {}).get("path", "")
            self.notebook_path = os.path.join(path, name)

        super().__init__(**kwargs)

    def __call__(self, output):
        """Return the first available format in the priority.

        Produces a UserWarning if no compatible mimetype is found.

        `output` is dict with structure {mimetype-of-element: value-of-element}

        """
        metadata = self.metadata.get(self.notebook_path, {})
        widgets_state = (
            metadata["widgets"][WIDGET_STATE_MIMETYPE]["state"]
            if metadata.get("widgets") is not None
            else {}
        )
        for fmt in self.display_data_priority:
            if fmt in output:
                # If there is no widget state available, we skip this mimetype
                if (
                    fmt == WIDGET_VIEW_MIMETYPE
                    and output[WIDGET_VIEW_MIMETYPE]["model_id"] not in widgets_state
                ):
                    continue

                return [fmt]
        warn(
            "Your element with mimetype(s) {mimetypes}"
            " is not able to be represented.".format(mimetypes=output.keys()),
            stacklevel=2,
        )

        return []
