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

"""
Basic utility functions.
"""

from elisa.core import common
from elisa.core.utils import defer, caching

import os.path


def get_and_cache_image(image_uri):
    """
    Get and cache an image for which we know a resource provider is available.

    If the image is local or already cached on disk, do not perform the
    request.

    The get request that may be performed to obtain the image is expected to
    return a L{elisa.plugins.base.models.media.RawDataModel}.

    @param image_uri: the URI of the image
    @type image_uri:  L{elisa.core.media_uri.MediaUri}

    @return: a deferred fired when the image was cached, with the full path to
             the cached file
    @rtype:  L{elisa.core.utils.defer.Deferred} with C{unicode}
    """
    cache_file = caching.get_cached_image_path(image_uri)
    if os.path.exists(cache_file):
        return defer.succeed(cache_file)

    def cache_data_to_file(model, cache_file):
        return caching.cache_to_file(model.data, cache_file)

    model, dfr = common.application.resource_manager.get(image_uri)
    dfr.addCallback(cache_data_to_file, cache_file)
    return dfr


def get_and_cache_thumbnail(item, thumbnail_uri):
    """
    Get and cache a thumbnail for a given item.

    If the thumbnail is local or already cached on disk, do not perform the
    request.

    The given thumbnail URI is assumed to have a corresponding resource
    provider registered and available (in case it is not a local resource).

    The get request that may be performed to obtain the thumbnail is expected
    to return a L{elisa.plugins.base.models.media.RawDataModel}.

    @param item:          any model for which we want to request a thumbnail
    @param thumbnail_uri: the URI to the distant thumbnail
    @type thumbnail_uri:  L{elisa.core.media_uri.MediaUri}

    @return: a deferred fired when the thumbnail was cached, with the full path
             to the cached file
    @rtype:  L{elisa.core.utils.defer.Deferred} with C{unicode}
    """
    # This is a two-level caching mechanism:
    #  1) First check if the item has a "thumbnail_path" attribute. If it does,
    #     trust that the referenced thumbnail exists and is valid;
    #  2) If not, compute the thumbnail path and get it where needed.
    try:
        # Note: the reference to the local path of the thumbnail being stored
        # in the item's "thumbnail_path" attribute is a convention that was
        # historically used here and there in various places of the code.
        # Change where it is stored at your own risk! It may (or may not) break
        # thumbnailing in various places, depending on how it was first
        # written.
        return defer.succeed(item.thumbnail_path)
    except AttributeError:
        def set_thumbnail_path(thumbnail_path, item):
            item.thumbnail_path = thumbnail_path
            return thumbnail_path

        dfr = get_and_cache_image(thumbnail_uri)
        dfr.addCallback(set_thumbnail_path, item)
        return dfr
