#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2011-2015 Slack
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from django.test import TestCase as TestCaseBase
from .scraper import beatport, discogs, itunes, junodownload, metalarchives, musicbrainz, bandcamp, musiksammler
from .result import ReleaseResult, ListResult, NotFoundResult, Result
import unittest


def todict(obj):
    if hasattr(obj, "__iter__"):
        return [todict(v) for v in obj]
    elif hasattr(obj, "__dict__"):
        return dict([(key, todict(value))
                     for key, value in obj.__dict__.iteritems()
                     if not callable(value) and not key.startswith('_')])
    else:
        return obj


class TestCase(TestCaseBase):

    maxDiff = None

    def setUp(self):
        self.addTypeEqualityFunc(ReleaseResult, 'assertResultEqual')
        self.addTypeEqualityFunc(ListResult, 'assertResultEqual')
        self.addTypeEqualityFunc(NotFoundResult, 'assertResultEqual')

    def assertResultEqual(self, d1, d2, msg=None):
        self.assertTrue(issubclass(d1.__class__, Result), 'First argument is not a Result')
        self.assertTrue(issubclass(d2.__class__, Result), 'Second argument is not a Result')

        self.assertEqual(d1.__class__.__name__, d2.__class__.__name__)
        self.assertEqual(todict(d1), todict(d2), msg)


class DiscogsTest(TestCase):

    def test_simple_album(self):
        expected = ReleaseResult()
        expected.set_scraper_name(None)

        release_event = expected.create_release_event()
        release_event.set_date(u'03 Nov 2000')
        release_event.set_country(u'Germany')
        expected.append_release_event(release_event)

        expected.set_format(u'CD, Album')

        label_id = expected.create_label_id()
        label_id.set_label(u'Richterskala')
        label_id.append_catalogue_nr(u'TRI 070 CD')
        expected.append_label_id(label_id)

        expected.set_title(u'Hast Du Mich Vermisst?')

        artist = expected.create_artist()
        artist.set_name(u'ASP')
        artist.set_various(False)
        artist.append_type(expected.ArtistTypes.MAIN)
        expected.append_release_artist(artist)

        expected.append_genre(u'Electronic')
        expected.append_genre(u'Rock')

        expected.append_style(u'Goth Rock')
        expected.append_style(u'Synth-pop')

        expected.set_url(u'http://www.discogs.com/ASP-Hast-Du-Mich-Vermisst/release/453432')

        disc = expected.create_disc()
        disc.set_number(1)
        disc.set_title(None)

        track = disc.create_track()
        track.set_number(u'1')
        track.set_title(u'Schwarzer Schmetterling')
        track.set_length(290)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'2')
        track.set_title(u'Where Do The Gods Go')
        track.set_length(226)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'3')
        track.set_title(u'Dancing')
        track.set_length(345)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'4')
        track.set_title(u'K\xfcss Mich')
        track.set_length(311)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'5')
        track.set_title(u'Sing Child')
        track.set_length(239)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'6')
        track.set_title(u'Teach Me War')
        track.set_length(225)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'7')
        track.set_title(u'Imbecile Anthem')
        track.set_length(222)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'8')
        track.set_title(u'Und Wir Tanzten (Ungeschickte Liebesbriefe)')
        track.set_length(305)
        disc.append_track(track
)

        track = disc.create_track()
        track.set_number(u'9')
        track.set_title(u'Blinded')
        track.set_length(443)
        disc.append_track(track)

        expected.append_disc(disc)

        scraper = discogs.ReleaseScraper.from_string(u'http://www.discogs.com/AS
P-Hast-Du-Mich-Vermisst/release/453432')
        result = scraper.get_result()

        self.assertEqual(expected, result)

    def test_multiple_cds(self):
        expected = ReleaseResult()
        expected.set_scraper_name(None)

        release_event = expected.create_release_event()
        release_event.set_date(u'25 May 2007')
        release_event.set_country(u'Germany')
        expected.append_release_event(release_event)

        expected.set_format(u'4 \xd7 CD, Compilation, Limited Edition, Digipak, Box Set, Limited Edition, Hand-Numbered')

        label_id = expected.create_label_id()
        label_id.set_label(u'[Trisol] Music Group GmbH')
        label_id.append_catalogue_nr(u'TRI 303 CD')
        expected.append_label_id(label_id)

        expected.set_title(u"The 'Once In A Lifetime' Recollection Box")

        artist = expected.create_artist()
        artist.set_name(u'ASP')
        artist.set_various(False)
        artist.append_type(expected.ArtistTypes.MAIN)
        expected.append_release_artist(artist)

        artist = expected.create_artist()
        artist.set_name(u'Chamber')
        artist.set_various(False)
        artist.append_type(expected.ArtistTypes.MAIN)
        expected.append_release_artist(artist)

        expected.append_genre(u'Classical')
        expected.append_genre(u'Non-Music')
        expected.append_genre(u'Rock')

        expected.append_style(u'Acoustic')
        expected.append_style(u'Goth Rock')
        expected.append_style(u'Classical')
        expected.append_style(u'Speech')

        expected.set_url(u'http://www.discogs.com/ASP-Chamber-The-Once-In-A-Lifetime-Recollection-Box/release/977684')

        disc = expected.create_disc()
        disc.set_number(1)
        disc.set_title(None)

        track = disc.create_track()
        track.set_number(u'1')
        track.set_title(u'Once In A Lifetime, Part 1')
        track.set_length(351)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'2')
        track.set_title(u"A Dead Man's Song")
        track.set_length(312)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'3')
        track.set_title(u'Versuchung')
        track.set_length(345)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'4')
        track.set_title(u'Torn')
        track.set_length(304)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'5')
        track.set_title(u'Demon Love')
        track.set_length(272)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'6')
        track.set_title(u'The Paperhearted Ghost')
        track.set_length(283)
        disc.append_track(track)

        track = disc.create_track()
        track.set_number(u'7')
        track.set_titl