#!/usr/bin/env python

import argparse
import inspect

from avaland import sources, MusicBase
from avaland.manager import SourceManager

inspect_sources = inspect.getmembers(sources, inspect.isclass)
available_sources = [i for i in inspect_sources if issubclass(i[1], MusicBase) and i[1] != MusicBase]

parser = argparse.ArgumentParser(description='Avaland Music Downloader')
parser.add_argument('query', type=str, help='Search query')
parser.add_argument('--path', '-p', type=str, help='Path to download music/album')
parser.add_argument('--sources', '-s', type=str,
                    help='List of sources (default: --sources all)\n'
                         'Available sources: ' + ", ".join(i[0] for i in available_sources), default=None)
parser.add_argument('--dl-first', '-df', help='Download first music in list', nargs='?', type=str, default='')
parser.add_argument('--dl-album', '-da', help='Download all musics in an album', nargs='?', type=str, default='')
parser.add_argument('--dl-artist', '-dr', help='Download all musics of an artist', nargs='?', type=str, default='')

args = parser.parse_args()


def response(_musics, _albums, _artists):
    counter = 1
    count_all = len(_musics) + len(_albums) + len(_artists)
    if len(_musics) == 0:
        return
    else:
        print('\nMusics:')

        for music in _musics:
            print('\t', '%s.%s' % (counter, " " * (len(str(count_all)) - len(str(counter)))),
                  '[%s]' % music.source.__site_name__, music.full_title)
            items.append(music)
            counter += 1

    if len(_albums) == 0:
        return
    else:
        print('\nAlbums:')
        for album in _albums:
            print('\t', '%s.%s' % (counter, " " * (len(str(count_all)) - len(str(counter)))),
                  '[%s]' % album.source.__site_name__, album.full_title)
            items.append(album)
            counter += 1

    if len(_artists) == 0:
        return
    else:
        print('\nArtists:')
        for artist in _artists:
            print('\t', '%s.%s' % (counter, " " * (len(str(count_all)) - len(str(counter)))),
                  '[%s]' % artist.source.__site_name__, artist.full_name)
            items.append(artist)
            counter += 1


if __name__ == '__main__':
    manager = SourceManager()
    sources = args.sources.split(",") if args.sources else None
    for i in available_sources:
        if not sources or i[0].lower() in sources or sources[0] == 'all':
            manager.register(i[1])

    search = manager.search(args.query)
    while True:
        items = []
        musics = []
        albums = []
        artists = []

        for source in search:
            musics.extend(search[source].musics)
            albums.extend(search[source].albums)
            artists.extend(search[source].artists)

        if args.dl_first is None:
            musics[0].download(args.path)
            exit()

        response(musics, albums, artists)

        _input = input('\nSelect an item to download (Press Q to exit): ')

        if _input.lower() == 'q':
            exit()

        while (not _input.isdigit()) or len(items) < int(_input) or int(_input) < 1:
            _input = input('(Invalid!) Select an item to download (Press Q to exit): ')
            if _input.lower() == 'q':
                exit()

        if type(items[int(_input) - 1]).__name__ == 'Music':
            items[int(_input) - 1].download(args.path)
            exit()
        else:
            search = {items[int(_input) - 1].source.__name__: items[int(_input) - 1].get_items()}
            if args.dl_album is None:
                if type(items[int(_input) - 1]).__name__ == 'Album':
                    for i in search[items[int(_input) - 1].source.__name__].musics:
                        i.download(args.path)
                    exit()
            if args.dl_artist is None:
                if type(items[int(_input) - 1]).__name__ == 'Artist':
                    for i in search[items[int(_input) - 1].source.__name__].musics:
                        i.download(args.path)
                    exit()
