# -*- coding: utf-8 -*-

import requests
from flask import jsonify
from utils.logger import logger
from utils.requester import get_data
from utils.cache import get_cache, set_cache

from apis.qq import qqAPI
from apis.kuwo import kuwoAPI
from apis.xiami import xiamiAPI
from apis.netease import neteaseAPI

class MusicRouter():
    def __init__(self):
        # Api object map
        self.api_map = {
            'qq': {
                'name': qqAPI.name,
                'single': qqAPI.single,
                'album': qqAPI.album,
                'info': qqAPI.info
            },
            'kuwo': {
                'name': kuwoAPI.name,
                'single': kuwoAPI.single,
                'album': kuwoAPI.album,
                'info': kuwoAPI.info
            },
            'xiami': {
                'name': xiamiAPI.name,
                'single': xiamiAPI.single,
                'album': xiamiAPI.album,
                'info': xiamiAPI.info
            },
            'netease': {
                'name': neteaseAPI.name,
                'single': neteaseAPI.single,
                'album': neteaseAPI.album,
                'info': neteaseAPI.info
            }
        }

        # Last.fm api config
        self.lastfm_conf = {
            'artist': 'http://ws.audioscrobbler.com/2.0/?method=artist.getinfo',
            'key': '57ee3318536b23ee81d6b27e36997cde',
            'format': 'json',
            'lang': 'zh'
        }
        self.lastfm = '%s&api_key=%s&format=%s&lang=%s&autocorrect=1' % (
            self.lastfm_conf.get('artist'),
            self.lastfm_conf.get('key'),
            self.lastfm_conf.get('format'),
            self.lastfm_conf.get('lang')
        )

        self.tips = {
            'cache_detected': u'Cache detected, directly return cache value...'
        }

    def log_req(self, params):
        """
        Log requests info
        
        Log detail requests info
        
        Arguments:
            params {dict} -- params
        """
        msg = 'API: %s, ' % params.get('API')
        for key in params.keys():
            if key != 'API':
                value = params.get(key)
                msg = msg + (u'%s: %s, ' %(key, value))
        msg = msg[:-2]

        logger.info(msg)

    def single(self, params):
        """
        Get single info
        
        Get single songs info
        
        Arguments:
            params {dict} -- params
        """
        src = params.get('src')
        sstr = params.get('sstr')
        page = params.get('page')
        single = self.api_map.get(src).get('single')
        cache_key = 'single_%s_%s_%s' % (src, sstr, str(page))
        cache_value = get_cache(cache_key)

        self.log_req({
            'API': 'single',
            'src': self.api_map.get(src).get('name'),
            'sstr': sstr,
            'page': page
        })

        # Check if cache exists first
        if cache_value != None:
            logger.info(self.tips.get('cache_detected'))
            return cache_value
        else:
            try:
                res = single(sstr, int(page))

                if res != None:
                    json = {
                        'status': 'success',
                        'data': {
                            'page': int(page),
                            'count': res.get('songs_count'),
                            'songs': res.get('songs_info')
                        }
                    }
                else:
                    json = { 'status': 'error', 'data': {} }

                res = jsonify(json)
                set_cache(cache_key, res)
            except requests.exceptions.Timeout:
                res = jsonify({ 'status': 'error', 'msg': 'connection timeout' })

            return res

    def album(self, params):
        """
        Get album info
        
        Get album info by album ID
        
        Arguments:
            params {dict} -- params
        """
        src = params.get('src')
        sstr = params.get('sstr')
        page = params.get('page')
        album = self.api_map.get(src).get('album')
        cache_key = 'album_%s_%s_%s' % (src, sstr, str(page))
        cache_value = get_cache(cache_key)

        self.log_req({
            'API': 'album',
            'src': self.api_map.get(src).get('name'),
            'sstr': sstr,
            'page': page
        })

        # Check if cache exists first
        if cache_value != None:
            logger.info(self.tips.get('cache_detected'))
            return cache_value
        else:
            try:
                res = album(sstr, int(page))

                if res != None:
                    json = {
                        'status': 'success',
                        'data': {
                            'page': int(page),
                            'count': res.get('songs_count'),
                            'songs': res.get('songs_info')
                        }
                    }
                else:
                    json = { 'status': 'error', 'data': {} }

                res = jsonify(json)
                set_cache(cache_key, res)
            except requests.exceptions.Timeout:
                res = jsonify({ 'status': 'error', 'msg': 'connection timeout' })

            return res

    def info(self, params):
        """
        Get song info
        
        Get song detail info
        
        Arguments:
            params {dict} -- params
        """
        src = params.get('src')
        song_id = params.get('song_id')
        info = self.api_map.get(src).get('info')
        cache_key = 'info_%s_%s' % (src, song_id)
        cache_value = get_cache(cache_key)
        src_name = self.api_map.get(src).get('name')

        self.log_req({
            'API': 'info',
            'src': src_name,
            'song_id': song_id
        })

        # Check if cache exists first
        if cache_value != None:
            logger.info(self.tips.get('cache_detected'))
            return cache_value
        else:
            try:
                res = info(song_id)

                if res != None:
                    json = {
                        'status': 'success' if res else 'copyright',
                        'data': {
                            'song_info': res,
                            'source': src_name
                        }
                    }
                else:
                    json = { 'status': 'error', 'data': {} }

                res = jsonify(json)
                set_cache(cache_key, res)
            except requests.exceptions.Timeout:
                res = jsonify({ 'status': 'error', 'msg': 'connection timeout' })

            return res

    def artist(self, params):
        """
        Get artist info
        
        Get artist info including bio and images
        
        Arguments:
            params {dict} -- dict
        """
        artist = params.get('artist')
        cache_key = 'artist_%s' % artist
        cache_value = get_cache(cache_key)

        self.log_req({
            'API': 'artist',
            'artist': artist
        })

        # Check if cache exists first
        if cache_value != None:
            logger.info(self.tips.get('cache_detected'))
            return cache_value
        else:
            url = '%s&artist=%s' % (self.lastfm, artist)
            try:
                res = get_data(url)
                if 'error' in res:
                    json = {
                        'status': 'error',
                        'artist': {}
                    }
                else:
                    artist = res.get('artist')
                    json = {
                        'status': 'success',
                        'artist': {
                            'name': artist.get('name'),
                            'bio': artist.get('bio').get('content'),
                            'images': artist.get('image')
                        }
                    }

                res = jsonify(json)
                set_cache(cache_key, res)
            except requests.exceptions.Timeout:
                res = jsonify({ 'status': 'error', 'msg': 'connection timeout' })

            return res

musicRouter = MusicRouter()
