# -*- coding: utf-8 -*-
# Elisa - Home multimedia server
# Copyright (C) 2006-2008 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 Elisa with Fluendo's plugins.
#
# The GPL part of Elisa is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Elisa" in the root directory of this distribution package
# for details on that license.

__maintainer__ = 'Philippe Normand <philippe@fluendo.com>'

from elisa.base_components.media_provider import MediaProvider, UriNotMonitorable
from elisa.base_components.media_provider import NotifyEvent
from elisa.core.component import InitializeFailure
from elisa.core.media_uri import MediaUri
from elisa.core import common
from elisa.core.observers.dict import DictObservable
from twisted.internet import defer, threads

from elisa.extern.translation import gettexter, N_
T_ = gettexter('elisa-youtube')


from youtube_client import YouTubeClient

import os, gst

plugin_registry = common.application.plugin_registry
InternetLocationMessage = plugin_registry.get_component_class('base:internet_location_message')

class YoutubeMedia(MediaProvider):
    """
    This class implements local filesystem support
    """
    default_config = {'user': ''}

    config_doc = {'user': 'Your Youtube username, optional'
                  }
        
    def initialize(self):
        try:
            gst.element_factory_make('flvdemux')
        except gst.PluginNotFoundError:
            msg = "Can't initialize flvdemux CVS version of gst-plugins-bad"
            raise InitializeFailure(self.name, msg)
        
        self._client = YouTubeClient()
        
        uri = "youtube:///"
        action_type = InternetLocationMessage.ActionType.LOCATION_ADDED
        msg = InternetLocationMessage(action_type, "YouTube", 'youtube', uri,
                                           media_types=['video',],
                                           theme_icon='youtube')
        common.application.bus.send_message(msg)
        self.debug("Initialize done")
        
    def scannable_uri_schemes__get(self):
        return {}
    
    def supported_uri_schemes__get(self):
        return { 'youtube': 0 }

    def get_media_type(self, uri):
        dfr = defer.Deferred()
        if self._is_directory(uri):
            dfr.callback({'file_type': 'directory', 'mime_type': ''})
        else:
            dfr.callback({'file_type': 'video', 'mime_type': 'video/x-flv'})
        return dfr

    def is_directory(self, uri):
        d = defer.Deferred()
        d.callback(self._is_directory(uri))
        return d

    def _is_directory(self, uri):
        return uri.scheme == 'youtube' and uri.host != 'video'

    def get_real_uri(self, uri):
        real_uri = None
        video_id = uri.path[1:]
        video_url = "http://www.youtube.com/watch?v=%s" % video_id
        real = self._client.get_flv_video_url(video_url)
        if real:
            real_uri = MediaUri(real)
        return real_uri

    def has_children_with_types(self, uri, media_types):
        dfr = defer.Deferred()
        
        has_children = False
        if self._is_directory(uri):
            if 'video' in media_types:
                has_children = True

        dfr.callback(has_children)
        return dfr

    def _build_main_menu(self, children):
        self.debug("Building main menu")
        child_uri = MediaUri('youtube://recently_featured/today')
        child_uri.label = T_(N_("Featured today"))
        children.append((child_uri, {}))

        child_uri = MediaUri('youtube://most_viewed')
        child_uri.label = T_(N_("Most viewed"))
        children.append((child_uri, {}))

        child_uri = MediaUri('youtube://top_rated')
        child_uri.label = T_(N_("Top rated"))
        children.append((child_uri, {}))

        child_uri = MediaUri('youtube://tags')
        child_uri.label = T_(N_("Tags"))
        children.append((child_uri, {}))

        user = self.config.get('user','')
        if user:
            child_uri = MediaUri('youtube://favorite_videos/%s' % user)
            child_uri.label = T_(N_("My favorite videos"))
            children.append((child_uri, {}))
            child_uri = MediaUri('youtube://user/%s' % user)
            child_uri.label = T_(N_("My videos"))
            children.append((child_uri, {}))
            child_uri = MediaUri('youtube://contacts/%s' % user)
            child_uri.label = T_(N_("My contacts"))
            children.append((child_uri, {}))
            
        return children
        

    def _retrieve_children(self, uri, children):
        videos = []
        users = []
        tags = {}
        
        host = uri.host
        if host == '':
            children = self._build_main_menu(children)
        elif host == 'contacts':
            username = uri.path[1:] # strip / from path
            users = self._client.get_contacts(username)
        elif host == 'recently_featured':
            videos = self._client.recently_featured()
        elif host == 'top_rated':
            videos = self._client.top_rated()
        elif host == 'most_viewed':
            videos = self._client.most_viewed()
        elif host == 'tags':
            tags = self._client.get_categories()
        elif host == 'tag':
            tagname = uri.path[1:] # strip / from path
            videos = self._client.get_category(tagname)
            
        elif host == 'favorite_videos':
            username = uri.path[1:] # strip / from path
            videos = self._client.favorite_videos(username)
        elif host == 'user':
            username = uri.path[1:] # strip / from path
            videos = self._client.videos_upload_by(username)

        for tag, label in tags.iteritems():
            child_uri = MediaUri('youtube://tag/%s' % tag)
            child_uri.label = label
            children.append((child_uri, {}))

        for video in videos:
            video_id = video.id.text.split("/")[-1]
            child_uri = MediaUri('youtube://video/%s' % video_id)
            child_uri.label = video.title.text
            thumbnail_url = self._client.get_largest_thumbnail(video)
            metadata = DictObservable()
            metadata['default_image'] = MediaUri(thumbnail_url)
            children.append((child_uri, metadata))
                
        if users is not None:
            for user in users:
                child_uri = MediaUri('youtube://user/%s' % user)
                child_uri.label = user
                children.append((child_uri, {}))
                
        return children


    def get_direct_children(self, uri, l):
        d = threads.deferToThread(self._retrieve_children, uri, l)
        return d

    def _blocking_open(self, uri, mode=None):
        return None

    def uri_is_monitorable(self, uri):
        return False
