import random

import httpx

import mucus.data
import mucus.exception


class Auth(httpx.Auth):
    def __init__(self, sid=None, arl=None):
        if sid is None or arl is None:
            data = mucus.data.get('auth')
            if data is not None:
                sid = data.get('sid')
                arl = data.get('arl')
        self.sid = sid
        self.arl = arl
        self.jwt = None

    def auth_flow(self, request):
        cookies = {}
        if self.arl is not None:
            cookies['arl'] = self.arl
        if self.sid is not None:
            cookies['sid'] = self.sid
        if cookies:
            request.headers['Cookie'] = '; '.join(f'{k}={v}' for k, v in cookies.items())
        response = yield request
        try:
            response.cookies['arl']
            response.cookies['sid']
        except KeyError:
            pass
        else:
            mucus.data.set('auth', {'sid': response.cookies['sid'],
                                    'arl': response.cookies['arl']})


class Client(httpx.Client):
    base_url = httpx.URL('https://www.deezer.com/ajax/')

    def __init__(self, auth=None):
        if auth is None:
            auth = Auth()

        super().__init__(auth=auth)

        self.data = UserData(self)

    def request(self, method, url, **kwargs):
        if url == 'deezer.getUserData':
            api_token = ''
        else:
            api_token = self.data.api_token

        kwargs['params'] = {
            'method': url,
            'input': 3,
            'api_version': '1.0',
            'api_token': api_token,
            'cid': random.randrange(0, 1000000000)
        }

        r = super().request(method, 'gw-light.php', **kwargs).json()
        if r.get('error'):
            raise mucus.exception.DeezerError(r['error'])

        return r['results']


class UserData:
    def __init__(self, client):
        self._data = client.post('deezer.getUserData')

    @property
    def api_token(self):
        return self._data['checkForm']

    @property
    def license_token(self):
        return self._data['USER']['OPTIONS']['license_token']

    @property
    def user_id(self):
        return self._data['USER']['USER_ID']
