# -*- 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: Gernot Klimscha <gernot@fluendo.com>

from twisted.trial.unittest import TestCase, SkipTest

from elisa.core.media_uri import MediaUri
from elisa.core.utils import defer
from elisa.core.utils.misc import run_functional_tests_check

from elisa.plugins.discogs.discogs_resource import DiscogsResource
from elisa.plugins.discogs.discogs_api import SERVER, generate_api_request

from elisa.plugins.base.models.audio import ArtistModel
from elisa.plugins.base.models.media import RawDataModel

from urllib import quote
import binascii


class TestDiscogsResource(TestCase):

    def setUp(self):
        class DummyHttp(object):
            def request_full(self, *args):
                self.request_full_args = args
                return defer.Deferred()

            def close(self):
                return defer.succeed(True)

        def created(resource):
            self.resource = resource
            self.resource._client = DummyHttp()

        return DiscogsResource.create({}).addCallback(created)

    def tearDown(self):
        return self.resource.clean()

    def test_request_encoded(self):
        """
        test that the request is always asking for gzipped data
        """
        uri = MediaUri("http://server.com/")
        model, dfr = self.resource.get(uri, None)

        request = self.resource._client.request_full_args[0]
        self.assertTrue(request.headers.hasHeader('accept-encoding'))
        self.assertEquals(request.headers.getRawHeaders('accept-encoding'), ['gzip'])

    def test_simple_parsing(self):
        """
        test for parsing some simple code
        """
        data ="""<resp stat="ok" version="1.0" requests="9"><artist><images><image height="369" type="secondary" uri="http://www.discogs.com/image/A-125246-1100178636.jpg" uri150="http://www.discogs.com/image/A-150-125246-1100178636.jpg" width="600" /><image height="250" type="secondary" uri="http://www.discogs.com/image/A-125246-1105986304.jpg" uri150="http://www.discogs.com/image/A-150-125246-1105986304.jpg" width="251" /><image height="341" type="secondary" uri="http://www.discogs.com/image/A-125246-1105986318.jpg" uri150="http://www.discogs.com/image/A-150-125246-1105986318.jpg" width="300" /><image height="250" type="secondary" uri="http://www.discogs.com/image/A-125246-1105986324.jpg" uri150="http://www.discogs.com/image/A-150-125246-1105986324.jpg" width="400" /><image height="540" type="secondary" uri="http://www.discogs.com/image/A-125246-1105986336.jpg" uri150="http://www.discogs.com/image/A-150-125246-1105986336.jpg" width="370" /><image height="317" type="secondary" uri="http://www.discogs.com/image/A-125246-1142199856.jpeg" uri150="http://www.discogs.com/image/A-150-125246-1142199856.jpeg" width="448" /><image height="454" type="secondary" uri="http://www.discogs.com/image/A-125246-1159160221.png" uri150="http://www.discogs.com/image/A-150-125246-1159160221.png" width="362" /></images><name>Nirvana</name><urls><url>http://www.geffen.com/nirvana/
</url><url>http://www.nirvanabox.com/
</url><url>http://www.nirvanaclub.com/
</url><url>http://www.nirvana-music.com/</url><url /></urls><members><name>Aaron Burckhard</name><name>Chad Channing</name><name>Dale Crover</name><name>Dan Peters</name><name>Dave Grohl</name><name>Jason Everman</name><name>Krist Novoselic</name><name>Kurt Cobain</name><name>Pat Smear</name></members><releases><release id="1145170" status="Accepted" type="Main"><title>In Utero</title><format>LP, Promo</format><label>EMI Records</label></release><release id="609680" status="Accepted" type="Main"><title>Interview Picture Disc</title><format>CD, Maxi</format><label>Tell Tales</label></release><release id="1195704" status="Accepted" type="Main"><title>Sliver / Dive</title><format>7", RE</format><label>Sub Pop Records</label></release><release id="848000" status="Accepted" type="Main"><title>Smells Like Teen Spirit</title><format>12", Pic</format><label>Geffen Records</label></release></releases></artist></resp>"""

        model = ArtistModel()
        result = self.resource._parse_xml_response(data, model)
        self.assertEquals(model.name, 'Nirvana')
        self.assertEquals(len(model.images), 7)
        d = model.images[4]
        self.assertTrue(isinstance(d.references[0], MediaUri))
        self.assertTrue(isinstance(d.references[-1], MediaUri))


class TestDiscogsResourceProviderFunctional(TestCase):

    """
    Functional tests for the discogs resource provider.
    Requires an internet connection.
    """

    def setUp(self):
        run_functional_tests_check()

        def created(provider):
            self.provider = provider

        dfr = DiscogsResource.create({})
        dfr.addCallback(created)
        return dfr

    def tearDown(self):
        return self.provider.clean()

    def test_get_artist(self):
        path = quote('/artist/Manu Chao')
        uri = generate_api_request(path)
        model, dfr = self.provider.get(uri)

        def got_response(model):
            self.failUnless(isinstance(model, ArtistModel))
            self.failUnlessEqual(model.name, 'Manu Chao')
            self.failIfEqual(model.images, [])

        dfr.addCallback(got_response)
        return dfr

    def test_get_image(self):
        uri = MediaUri('%s/image/A-150-30773-1100796130.jpg' % SERVER)
        image_size = 4321
        model, dfr = self.provider.get(uri)

        def got_response(model):
            self.failUnless(isinstance(model, RawDataModel))
            self.failUnlessEqual(model.size, image_size)
            header = 'ffd8' + 'ffe0' # SOI marker + JFIF marker
            self.failUnlessEqual(binascii.hexlify(model.data[:4]), header)

        dfr.addCallback(got_response)
        return dfr

    def test_wrong_path(self):
        uri = generate_api_request(u'/wrong/Fail')
        model, dfr = self.provider.get(uri)
        self.failUnlessFailure(dfr, IOError)
        return dfr
