"""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
#-----------------------------------------------------------------------------

from warnings import warn
import os
from ..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):
        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())
                      )

        return []
