# -*- coding: utf-8 -*-
# Moovida - Home multimedia server
# Copyright (C) 2008-2009 Fluendo Embedded S.L. (www.fluendo.com).
# All rights reserved.
#
# This file is available under one of two license agreements.
#
# This file is licensed under the GPL version 3.
# See "LICENSE.GPL" in the root of this distribution including a special
# exception to use Moovida with Fluendo's plugins.
#
# The GPL part of Moovida is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Moovida" in the root directory of this distribution package
# for details on that license.
#
# Author: Olivier Tilloy <olivier@fluendo.com>

from elisa.core.components.model import Model
from elisa.core.plugin import Plugin
from elisa.core.media_uri import MediaUri
from elisa.core.utils import defer
from elisa.core.plugin_registry import get_plugin_toplevel_directory

from elisa.plugins.base.models.image import ImageModel

import pkg_resources

import os


class PluginModel(Model, Plugin):

    """
    A model that represents a plugin and its metadata.

    @note: this model may be enriched along the way with new metadata

    @ivar icons:        a list of icons for the plugin
    @type icons:        C{list} of
                        L{elisa.plugins.base.models.image.ImageModel}
    @ivar screenshots:  a list of screenshot images for the plugin
    @type screenshots:  C{list} of
                        L{elisa.plugins.base.models.image.ImageModel}
    """

    def __init__(self):
        super(PluginModel, self).__init__()
        self.icons = []
        self.screenshots = []

    @classmethod
    def from_dict(cls, dictionary):
        """
        Class method that instantiates and returns a plugin model from a
        dictionary as provided by the plugin repository.

        @param dictionary: a dictionary as provided by the plugin repository
        @type dictionary:  C{dict}

        @return:           a plugin model populated accordingly
        @rtype:            L{PluginModel}
        """
        plugin = super(PluginModel, cls).from_dict(dictionary)
        for key, value in dictionary.iteritems():
            if key == 'icons':
                icons = eval(value)
                for icon in icons:
                    model = ImageModel()
                    model.references.append(MediaUri(icon['uri']))
                    plugin.icons.append(model)
            elif key == 'screenshots':
                screenshots = eval(value)
                for screenshot in screenshots:
                    model = ImageModel()
                    model.references.append(MediaUri(screenshot['uri']))
                    plugin.screenshots.append(model)
        return plugin

    def _extract_resources(self, distribution, folder):
        toplevel_directory = get_plugin_toplevel_directory(distribution)
        sub_directory = '%s/%s' % (toplevel_directory, folder)
        if not distribution.resource_isdir(sub_directory):
            return []
        resources = distribution.resource_listdir(sub_directory)
        resources.sort()
        parsed_resources = []
        requirement = \
            pkg_resources.Requirement.parse(distribution.project_name)
        for resource in resources:
            if resource.startswith('__'):
                continue
            resource_path = '%s/%s' % (sub_directory, resource)
            path = pkg_resources.resource_filename(requirement, resource_path)
            icon_uri = {'scheme': 'file', 'path': path}
            model = ImageModel()
            model.references.append(MediaUri(icon_uri))
            parsed_resources.append(model)
        return parsed_resources

    @classmethod
    def from_distribution(cls, distribution):
        """
        Class method that instantiates and returns a plugin model from a
        distribution as provided by L{pkg_resources}.

        @param distribution: a distribution as provided by L{pkg_resources}
        @type distribution:  L{pkg_resources.Distribution}

        @return:             a plugin model populated accordingly
        @rtype:              L{PluginModel}
        """
        plugin = super(PluginModel, cls).from_distribution(distribution)
        plugin.icons = plugin._extract_resources(distribution, 'icons')
        plugin.screenshots = plugin._extract_resources(distribution,
                                                       'screenshots')
        return plugin
