# -*- coding: utf-8 -*-
# Moovida - Home multimedia server
# Copyright (C) 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>

"""
Internal representation of a plugin.
"""

from distutils.version import LooseVersion
import pkg_resources


class Plugin(object):

    """
    A plugin and its metadata.

    @ivar name:         the name of the plugin
    @type name:         C{unicode}
    @ivar version:      the version number of the plugin
    @type version:      L{distutils.version.LooseVersion}
    @ivar author_name:  the name of the author of the plugin
    @type author_name:  C{unicode}
    @ivar author_email: the e-mail address of the author of the plugin
    @type author_email: C{unicode}
    @ivar platforms:    a list of compatible platforms (typical values are:
                        C{linux}, C{win32}, C{macosx})
    @type platforms:    C{list} of C{unicode}
    @ivar license:      the license of the plugin
    @type license:      C{unicode}
    @ivar website:      the home page of the plugin
    @type website:      C{unicode}
    @ivar category:     a unique category the plugin belongs to
    @type category:     C{unicode}
    @ivar tags:         a list of tags that define the plugin
    @type tags:         C{list} of C{unicode}
    @ivar egg_name:     the egg name
    @type egg_name:     C{unicode}
    @ivar uri:          the URI where the egg can be downloaded from
    @type uri:          C{unicode}
    @ivar title:        a fancy (short) name for the plugin
    @type title:        C{unicode}
    @ivar description:  a detailed description of what the plugin does
    @type description:  C{unicode}

    @ivar enabled:      whether the plugin is currently enabled
    @type enabled:      C{bool}
    """

    def __init__(self):
        self.name = ''
        self.version = LooseVersion()
        self.author_name = ''
        self.author_email = ''
        self.platforms = []
        self.license = ''
        self.website = ''
        self.category = ''
        self.tags = []
        self.egg_name = ''
        self.uri = ''
        self.title = ''
        self.description = ''
        self.enabled = False

    def runs_on_current_platform(self):
        """
        Test whether the plugin is compatible with the current platform.

        @return: C{True} if compatible with the current platform, C{False}
                 otherwise
        @rtype:  C{bool}
        """
        if len(self.platforms) == 0:
            # No platform specified, the plugin is cross-platform.
            return True

        current_platform = pkg_resources.get_platform()
        for platform in self.platforms:
            if current_platform.startswith(platform):
                return True

        return False

    @classmethod
    def from_distribution(cls, distribution):
        """
        Class method that instantiates and returns a plugin object 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 object populated accordingly
        @rtype:              L{Plugin}
        """
        plugin = cls()
        plugin.name = distribution.project_name
        plugin.version.parse(distribution.version)
        plugin.author_name = distribution.author
        if distribution.platform is not None:
            plugin.platforms = [distribution.platform]
        plugin.license = distribution.license
        plugin.egg_name = distribution.egg_name()
        plugin.title = distribution.summary
        plugin.description = distribution.description
        return plugin

    @classmethod
    def from_dict(cls, dictionary):
        """
        Class method that instantiates and returns a plugin object 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 object populated accordingly
        @rtype:            L{Plugin}
        """
        plugin = cls()
        for key, value in dictionary.iteritems():
            if key in ('name', 'author_name', 'author_email', 'license',
                       'website', 'category', 'tags', 'egg_name', 'uri',
                       'description'):
                setattr(plugin, key, value)
            elif key == 'version':
                plugin.version.parse(value)
            elif key == 'platforms':
                # Platforms is a comma-separated list of platforms serialized
                # as a string.
                platforms = value.split(',')
                for platform in platforms:
                    platform = platform.strip()
                    if platform != 'UNKNOWN':
                        plugin.platforms.append(platform)
            elif key == 'summary':
                plugin.title = value
        return plugin
