import httpx

import mucus.deezer.decrypter
import mucus.exception

default_formats = ('FLAC', 'MP3_320', 'MP3_128', 'MP3_64', 'MP3_MISC')


def stream(song, license_token, formats=default_formats):
    r = httpx.post('https://media.deezer.com/v1/get_url', json={
        'license_token': license_token,
        'media': [
            {
                'type': 'FULL', 'formats': [
                    {
                        'cipher': 'BF_CBC_STRIPE',
                        'format': fmt
                    } for fmt in formats
                ]
            }
        ],
        'track_tokens': [song['TRACK_TOKEN']]
    }).json()
    try:
        raise mucus.exception.DeezerStreamError(r['data'][0]['errors'])
    except (IndexError, KeyError):
        pass
    media = r['data'][0]['media'][0]
    yield media
    source = media['sources'][0]
    yield source
    decrypter = mucus.deezer.decrypter.Decrypter(song['SNG_ID'])
    pos = 0
    while True:
        try:
            with httpx.stream('GET', source['url'], headers={'range': f'bytes={pos}-'}, timeout=1.0) as r: # noqa
                for chunk in r.iter_bytes(chunk_size=2048):
                    if (pos // 2048) % 3 == 0 and len(chunk) == 2048:
                        chunk = decrypter.decrypt(chunk)
                    yield chunk
                    pos += len(chunk)
                return
        except httpx.HTTPError:
            continue
