#!/usr/bin/env python3
"""
    * ytmdl.py - A script to download songs.

----------------------------------------------------
     A simple script to download songs in mp3 format
     from Youtube.
     Users pass the song name as arguement.
----------------------------------------------------
    --> Deepjyoti Barman
    --> deepjyoti30@github.com
"""

from __future__ import unicode_literals
import sys
from colorama import init
from colorama import Fore, Style
import argparse
from ytmdl import (
            dir,
            song,
            yt,
            defaults,
            prepend,
            setupConfig,
            cache,
            utility,
            metadata,
            logger
)

# init colorama for windows
init()

logger = logger.Logger('ytmdl')


def arguments():
    """Parse the arguments."""
    parser = argparse.ArgumentParser()

    parser.add_argument('SONG_NAME', help="Name of the song to download.",
                        type=str, nargs="+")
    parser.add_argument('-q', '--quiet',
                        help="Don't ask the user to select songs\
                        if more than one search result.\
                        The first result in each case will be considered.",
                        action='store_true')
    parser.add_argument('--choice', help="The choice that the user wants\
                        to go for. Usefull to pass along with --quiet.\
                        Choices start at 1", choices=range(1,50),
                        type=int, default=None, metavar="CHOICE")
    parser.add_argument('--artist', help="Name of the artist")
    parser.add_argument('--album', help="Name of the album.")
    parser.add_argument('--version', action='version', version='2019.11.15',
                        help='show the program version number and exit')
    parser.add_argument('--url',
                        help="Youtube song link.")
    parser.add_argument('--disable-metaadd', help="Disable addition of\
                        passed artist and album keyword to the youtube search\
                        in order to get a more accurate result. (Default: false)",
                        action="store_true")
    parser.add_argument('-s', '--setup',
                        help='Setup the config file',
                        action='store_true')
    parser.add_argument('--list', help="Download list of songs.\
                        The list should have one song name in every line.",
                        default=None)
    parser.add_argument('--nolocal',
                        help='Dont search locally for the song before\
                        downloading.',
                        action='store_true')

    args = parser.parse_args()

    return args


def main(args):
    """Run on program call."""
    # args = arguments()
    song_name = ' '.join(args.SONG_NAME)

    # Check if --setup is passed
    if args.setup:
        setupConfig.make_config()
        exit(0)

    if not args.nolocal:
        # Search for the song locally
        if not cache.main(song_name):
            return 0

    is_quiet = args.quiet
    url = args.url
    passed_choice = args.choice

    # If the url is passed then get the data
    if url is not None:
        data = []
        # Get video data from youtube
        temp_data = yt.scan_video(yt.get_href(url))
        data.append(temp_data)

        # link to dw the song
        link = url

        # In this case choice will be 0
        choice = 0
    else:
        if is_quiet:
            logger.info('Quiet is enabled')

        logger.info('Searching Youtube for {}{}{}'.format(
                Fore.LIGHTYELLOW_EX,
                song_name,
                Style.RESET_ALL
        ))

        data, urls = yt.search(song_name, not args.disable_metaadd,
                                kw=[args.artist, args.album])
        
        # Handle the exception if urls has len 0
        if len(urls) == 0:
            logger.critical("No song found. Please try again with a different keyword.")

        if len(data) > 1 and not is_quiet:
            # Ask for a choice
            choice = song.getChoice(data, 'mp3')
        else:
            if passed_choice is not None and passed_choice <= len(data):
                choice = passed_choice - 1
                logger.info("Using {} as choice".format(passed_choice))
            else:
                choice = 0

        link = 'https://youtube.com{}'.format(urls[int(choice)])

    # Declare a var to store the name of the yt video
    yt_title = data[choice]['title']

    logger.info('Downloading {}{}{} in {}{}kbps{}'.format(
        Fore.LIGHTMAGENTA_EX,
        yt_title,
        Style.RESET_ALL,
        Fore.LIGHTYELLOW_EX,
        defaults.DEFAULT.SONG_QUALITY,
        Style.RESET_ALL
    ))
    path = yt.dw(link, yt_title)

    if type(path) is not str:
        logger.critical("ERROR: {}".format(path))
    else:
        logger.info('Downloaded!')

    logger.info('Converting to mp3...')

    conv_name = utility.convert_to_mp3(path)

    if type(conv_name) is not str:
        logger.critical('ERROR: {}'.format(conv_name))

    logger.info('Getting song data...')

    TRACK_INFO = metadata.SEARCH_SONG(song_name, filters=[args.artist, args.album])

    # declare a variable to store the option
    option = 0

    if TRACK_INFO is False:
        # prepend.PREPEND(2)
        # print('Data \a')
        # exit(0)
        pass
    elif len(TRACK_INFO) == 0:
        logger.critical('No data was found!\a')
    else:
        prepend.PREPEND(1)
        print('Setting data...')

        option = song.setData(TRACK_INFO, is_quiet, conv_name, passed_choice)

        if type(option) is not int:
            logger.critical('ERROR: {}'.format(option))

    # Get the directory where song is moved

    DIR = dir.cleanup(TRACK_INFO, option)
    logger.info('Moving to {}...'.format(DIR))

    if type(DIR) is not str:
        logger.critical('ERROR: {}'.format(DIR))
    else:
        logger.info('Done')


def extract_data():
    """Extract the arguments and act accordingly."""
    args = arguments()

    if args.list is not None:
        songs = utility.get_songs(args.list)
        if len(songs) != 0:
            logger.info("Downloading songs in {}".format(args.list))
            for song_name in songs:
                args.SONG_NAME = song_name
                main(args)
        else:
            logger.info("{}: is empty".format(args.list))
    else:
        main(args)


if __name__ == '__main__':
    try:
        extract_data()
    except KeyboardInterrupt:
        logger.info("Exiting..!")
