from .requester import Requester
from .tools import *

class AZlyrics(Requester):
    """
    Fast and Secure API for AZLyrics.com.

    Attributes:
        title (str): song title.
        artist (str): artist name.
        search_engine (str): search engine used to assist scraping lyrics.
            - currently available: 'google', 'duckduckgo'.
        accuracy (float): used to determine accuracy via jaro algorithm.
        proxies (dict): if you want to use proxy while connecting to 'AZLyrics.com'.
    """
    
    def __init__(self, search_engine='', accuracy=0.6, proxies={}):
        self.title = ''
        self.artist = ''
        self.search_engine = search_engine
        
        self.accuracy = accuracy
        if not 0 < accuracy <= 1:
            self.accuracy = 0.6
        
        self.proxies = proxies

        self.lyrics_history = []
        self.lyrics = ''
        self.songs = {}

    def getLyrics(self, url=None, ext='txt', save=False, path='', sleep=3):
        """
        Retrieve Lyrics for a given song details.
        
        Parameters: 
            url (str): url of the song's Azlyrics page. 
            ext (str): extension of the lyrics saved file, default is ".txt".
            save (bool): allow to or not to save lyrics in a file.
            sleep (float): cooldown before next request.  
        
        Returns:
            lyrics (str): Lyrics of the detected song.
        """

        # Best cooldown is 5 sec
        time.sleep(sleep)

        link = url

        if not url:
            # v3.0.5: No need for artist and title if url is found
            if not self.artist + self.title:
                raise ValueError("Both artist and title can't be empty!")
            if self.search_engine:
                # If user can't remember the artist,
                # he can search by title only
                
                # Get AZlyrics url via Google Search
                link = googleGet(
                            self.search_engine,
                            self.accuracy,
                            self.get,
                            self.artist,
                            self.title,
                            0,
                            self.proxies
                        )
                if not link:
                    return 0
            else:
                # Sometimes search engines block you
                # If happened use the normal get method
                link = normalGet(
                            self.artist,
                            self.title,
                            0)

        page = self.get(link, self.proxies)
        if page.status_code != 200:
            if not self.search_engine:
                print('Failed to find lyrics. Trying to get link from Google')
                self.search_engine = 'google'
                lyrics = self.getLyrics(url=url, ext=ext, save=save, path=path, sleep=sleep)
                self.search_engine = ''
                return lyrics
            else:
                print('Error',page.status_code)
                return 1

        # Getting Basic metadata from azlyrics
        metadata = [elm.text for elm in htmlFindAll(page)('b')]
        
        # if metadata is empty, then it's not a valid page
        if not metadata:
            print('Error', 'no metadata')
            return 1
        
        # v3.0.4: Update title and artist attributes with exact names
        self.artist = filtr(metadata[0][:-7], True)
        self.title = filtr(metadata[1][1:-1], True)

        lyrics = parseLyric(page)
        self.lyrics = lyrics.strip()

        # Saving Lyrics
        if lyrics:
            if save:
                # v3.0.2: Adding custom path
                p = os.path.join(
                                path,
                                '{} - {}.{}'.format(
                                                self.title.title(),
                                                self.artist.title(),
                                                ext
                                                )
                                )
                
                with open(p, 'w', encoding='utf-8') as f:
                    f.write(lyrics.strip())
            
            # Store lyrics for later usage
            self.lyrics_history.append(self.lyrics)
            return self.lyrics

        self.lyrics = 'No lyrics found :('
        return 2

    def getSongs(self, sleep=3):
        """
        Retrieve a dictionary of songs with their links.

        Parameters:
            sleep (float): cooldown before next request.  
        
        Returns:
            dict: dictionary of songs with their links.
        """

        if not self.artist:
            raise Exception("Artist can't be empty!")
        
        # Best cooldown is 5 sec
        time.sleep(sleep)
        
        if self.search_engine:
            link = googleGet(
                        self.search_engine,
                        self.accuracy,
                        self.get,
                        self.artist,
                        '',
                        1,
                        self.proxies
                    )
            if not link:
                return {}
        else:
            link = normalGet(
                        self.artist,
                        '',
                        1)
        
        albums_page = self.get(link, self.proxies)
        if albums_page.status_code != 200:
            if not self.search_engine:
                print('Failed to find songs. Trying to get link from Google')
                self.search_engine = 'google'
                songs = self.getLyrics(sleep=sleep)
                self.search_engine = ''
                return songs
            else:
                print('Error',albums_page.status_code)
                return {}
        
        # Store songs for later usage
        self.songs = parseSongs(albums_page)
        return self.songs
