# Copyright(c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""FileUpload class.

Represents a file upload button.
"""

from traitlets import (
    observe, default, Unicode, Dict, List, Int, Bool, Bytes, CaselessStrEnum
)

from .widget_description import DescriptionWidget
from .valuewidget import ValueWidget
from .widget_core import CoreWidget
from .widget_button import ButtonStyle
from .widget import register, widget_serialization
from .trait_types import bytes_serialization, InstanceDict

def content_from_json(value, widget):
    """
    deserialize file content
    """
    from_json = bytes_serialization['from_json']
    output = [from_json(e, None) for e in value]
    return output


@register
class FileUpload(DescriptionWidget, ValueWidget, CoreWidget):
    """
    Upload file(s) from browser to Python kernel as bytes
    """
    _model_name = Unicode('FileUploadModel').tag(sync=True)
    _view_name = Unicode('FileUploadView').tag(sync=True)
    _counter = Int().tag(sync=True)

    accept = Unicode(help='File types to accept, empty string for all').tag(sync=True)
    multiple = Bool(help='If True, allow for multiple files upload').tag(sync=True)
    disabled = Bool(help='Enable or disable button').tag(sync=True)
    icon = Unicode('upload', help="Font-awesome icon name, without the 'fa-' prefix.").tag(sync=True)
    button_style = CaselessStrEnum(
        values=['primary', 'success', 'info', 'warning', 'danger', ''], default_value='',
        help="""Use a predefined styling for the button.""").tag(sync=True)
    style = InstanceDict(ButtonStyle).tag(sync=True, **widget_serialization)
    metadata = List(Dict(), help='List of file metadata').tag(sync=True)
    data = List(Bytes(), help='List of file content (bytes)').tag(
        sync=True, echo_update=False, from_json=content_from_json
    )
    error = Unicode(help='Error message').tag(sync=True)
    value = Dict(read_only=True)

    @observe('_counter')
    def on_incr_counter(self, change):
        """
        counter increment triggers the update of trait value
        """
        res = {}
        msg = 'Error: length of metadata and data must be equal'
        assert len(self.metadata) == len(self.data), msg
        for metadata, content in zip(self.metadata, self.data):
            name = metadata['name']
            res[name] = {'metadata': metadata, 'content': content}
        self.set_trait('value', res)

    @default('description')
    def _default_description(self):
        return 'Upload'
