"""Tests for avatar generator of Habiticalib."""

import asyncio
from io import BytesIO
import pathlib

from aiohttp import ClientSession
from aioresponses import aioresponses
import pytest
from syrupy.assertion import SnapshotAssertion
from yarl import URL

from habiticalib import Habitica
from habiticalib.types import UserStyles

from .conftest import load_fixture

TEST_AVATAR = b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x8d\x00\x00\x00\x93\x08\x06\x00\x00\x00\xb3\x82\x9aN\x00\x00\x0c=IDATx\x9c\xed\x9d}pVG\x15\xc6o(\x08E\xbeI\x00C\xb0Q\x08P@)\x85\xd0\x12I\x07\x04\xca\x14i\xc1\xd1\xa1\xc0\xb4J!\"\xb4J\xa7\x95RKG\x8a8\x82\xa4\x19\xc6A\xc0Z\xa1\xe0\x07f\xa8\x82S\x8b|\x16354\x14B\x84*\x1f\x81P'@\x08P\xa0\t_\x01*P\xff\xdb\xf3\\\xdd\x9d\xf7\x9e\xde\xf7\xe3F\x9f\xdf_\x87\xcd\xde\xbd\xf7\xbe==\xcf\x9c\xddsw\xd3V,\xaa\xfa\xd8#DA\x93T?\x00i|\xd0i\x88\x9a\xa6\xf8\x8f\x01\xb9]R\xf5\x1c$\xe2\xec+?clF\x1a\xa2\x86NC\xd44\x8d\xdd\xa5\xf1\xf0\xfa\xf7\xbb\xc5\xec3\xe1''\x93\xf0$\xe1Y\xf2\xf5\x8c\x98}\x9e\xfd\xc3\xb9$<\xc9\x7f\xc3HC\xd4\xd0i\x88\x9aF)O\xa7\x7f\x9aom\x9f\xf9\xcc\xe3\xd6\xf6\xfa\xbd\xfb\x8c]\x0c\x12Vs\xec\xba\xb1S\x15\xea]2\xb4\xbc\xec\xd7\xd6\xf6\xfa}\xa5\xc6~\xd1qm\xa2\xdf\x85\x91\x86\xa8\xa1\xd3\x105\x8dF\x9eP\x92\x86\x16\xce56\x86\xeb\x03\xc5\xa5^,\xf2\xbbd\x1b;+\xbf\x95\xb1_\x86P\x9f\xe8\xf0\x8e\x92\xe4\x92\xa1\x9ds\x16\xc6\x1c\xe7\xc7\xcb\xbfem\x7f1\xc1\xef\xc2HC\xd4\xd0i\x88\x9aH\xcb\x93K\x92\\\xa1\xbb\xf4Lu\xcc1Q\x9ej\xaa\xae\x18\xfb\xb9'\x06\x19;\x11R\xe5\x92\xa40\xef\xe2\x15\x8b\x99\x95#R\x8b\xb2\x95\x08\xa9b\xa4!j\xe84DM\x1aV\xeeE\xa14\x02\xd7\x8fp\xb2\xce\x95\x19a\x18\x7f\xeb\xe0\x15k\x9f\x91}[Y\xdbQ\xaa\\\x14\xef\xac46\x86\xf7\xe9\x0f\xb7\xb7\xf6\x7f\xf5\xcd:k\x9f\xf5+g\x1a;\xc8\xbb A\xde\xcb\x97\x15\xe6\xd8\xdf\xf7\xe5\xd5{\x8d\xad\x95*\x96F\x90P\xd0i\x88\x9aHgO\xb8f\x84\xb8$\t\xa5\x01A\x99\xf8\xe1\x88~\xd6q\\R5iho\xeb8\x8b\x9b\xf7\xb3u\xf7\xf5Y5\xe3~c\x87\x91\xa4 \xef\xe5y2N\xbe\x97ml\x97T\x85\x81\x91\x86\xa8\xa1\xd3\x105\x91\x93',W\xa8\xe9b\xcf\x1a\x82\x84n\xc4\x95\xd1\x04\x91\xaa\x97v\x1c06JR\xbf{\xa4\x0f\xb2x\xbf\xd8\xd3^y\xf7\x13\xdf+\xcc{\xe5;\x92\xe0\xca\x1b7c\x8e\x19\x04F\x1a\xa2\x86NC\xd4DB\x9ep]\x06\xd7\x80pm(\xd0Z\x8c\x12\xd7\x98\xaev\x94\xa4V\x03r\x8c}e_U\xdc\xef\x15\x06\x9f\xfcA&\x85\xd9\xdc4\x90\xb3 R\x880\xd2\x105t\x1a\xa2&\x12\xf2\x14\x04m\xc6\xe4\xc2\x95q\xe0:\x0e\xde\xab\xe4\x0b5\xc6\xbep\xf5\x82\xb1[\xbe\xd3Ql\x18\xbf{\x8e\xf4)I\x93>\xc3\xff\x91\x15\xf3^a\xdek\xe0\xf0\\\x19\xb3\xa4\xdc\xd8\xaeL*\x0c\x8c4D\r\x9d\x86\xa8\x89\x84<\xe1\xa4\x13fL\xb8n\xd2{\xa7\xfdQ\xff\xb2a\xaa\xb1\xcf\xef\xd9n\xec\xf4\xc1\xa3\x8c]U-\x12\xf3\xedg\xb7Y\xc7A\x99(n/%\x04\r-g\x18\xfbN\xe8\xdf`\x1d\xc5\xf3\xde\xdf_-6\xb4o\xbd\xf4/c\x8fn\xd3\xccq\xb5\x1d\xd7\xe7\xc6\xaeO\x8c{7O\xec\x7fVF\x1a\xa2\x86NC\xd4\xa4L\x9e\xba\xb5\xb4O.\xf9J\x0brd2*\xabG\x0bc\xa3$\xa1\xf4\xe4\x80$ed\x88\x1c\xdc\xdbS\xb2\x98_,y\xd0\xd8\xe3\xdb\xa6\x1b\xfb\xd1&[\x8c=\xa9N&\x18\xbd\xddb\xba\xd6\x9e\x0e\x80$!\xf7\x9c\x93\xd2\x8eo.\x92v\x94\xaa\xa73D\xf4\xa6;&\xdcp=\x0e\x8b\xd2\x17}Cd\xeb*\xf4\xc1\xdf\n%\x1e\xd7\xc20\xdb\xd2\xc2HC\xd4\xd0i\x88\x9a\xd4eO\xd5\xb0L\xdf\xc9\xde\x053\xa9\xbaNw\x1b\xfb\xc1\x9e\xd7\x8c\x9d\x91\xd1\xd9\xd8e\xe5\"U\x9e\x97\x05\xedg\xad\xe3\x9f\xbc\xf7s\xc6n\xd30_\xfe\x00\x92\xb4y\x95<\xe7C\xd3\xa0Lb\xbf\xfd\x99\x9f\xbf!}6\xff>\xcd\xd8\xbfzAv\xde\xfdy\xb7\xcf\xd8/\x0e@\xf5/\x97\x1a;\xc8.\x19\xf8\x1b\xc6\x0bF\x1a\xa2\x86NC\xd4\xa4L\x9eNv\xbalmweR7{\xb5\x91N\xdbz\x19sw\xed\x11c?\x967\xc2\xd8\xbe\xac*[\xa4\n\xb3\xaan\xedEz\xe6m\x13\t\xf3e\x16\xd9\xb2\x8e\x83\x04\xc9\x9e\xbcl\xf9y1K\xea\xdd\xa2\x9d\xbd?P\xb4X\xde}\xd9{\x1b\x8d=\xab\xffxc?\xe7\xb8\x16%\t\xab\x01'>\xf1Uc\xe3\xef\xa3\x85\x91\x86\xa8\xa1\xd3\x105\x91X{B\xa6\xce\xbeK\xfe\x01\x924w\xdeS\xc6^\xbbv\x9d\xb1\xd3>\x92\xb5\xff\x0ey\x92\x95\x8c\x18)\xdf+\xedX\xf9\x96\xb1\xab\xaa\xed\xf7E\t\xdb\xff\xbb7\x8d\xdd\xb0\x15\x8b\xb1\xe5\xe7rJ\x12\xe0\xba\xb6\xf2z}\xcck\x0f\x9f\xeai\xec\xf6\xe9\xf2.\xef\\\xed.\x9d\xe03[\x04\xd7\xf2\xbe;g\xac\xb11\xbbt\xad\xc1\x05\x81\x91\x86\xa8\xa1\xd3\x105I\xdd5\x02\xd7\x9bF=\xd9\xc6\xda\x07e\xe8J\xc3Ec\xbf\xf1GY\x1b:q\x18B}\xa5\xec\xea0\xe5\xe9\x81\xc6\xce\x1d8\xc4\xd8\xe5\x15\xbb\x8c}\xfb\x88\\\x8b\x92\xa4\xcd&&\x94]\xb3\xb6\xaf\xf6*\xad\xed\x981\xa1<\xa1\x94\xfch\xa8\xac\x19\xcd}{\xa8\xb1\xeb?\x96\x12\x88!\xc3$[<tN~\xc3\xfb2%\xa3\xcc\xcb\x95\t\xcfs\xe7\xece\x18A\xcaE\x10\xee\x1aABA\xa7!j\x92\x9a=\xa1$\xb9d\xa8\xa4t\x8bg#\xf3\xb3m\xc1\x96\xf6\xfbG\xdb%)\x08\x18\xa21\xa4\xe3\xa4\xdf\xbamR(\x8e\x92\x84kL\x08\x96O\xecj!!\xdd%I\x17n\x8a\xac\xcc}[J\x1dP\x92\xda\xe5\xc8\xba\xd5\xb2\x952\xd1\xf7\x9d\x02\xc9\x8c\x10\x94$\x97\xec2{\"I\x85NC\xd4\xa4lro\xe1\x82\xe5q\x1f3\x88<5\xe9%\xd2\x80\x99\x94\xab|\xa2\x02\xbe!\xaa\x80\xf6\x82\xb1\xfd\xad\xfd\x9f\xdf\xf8\x9e\xfc\xe3\x86\xfd\x19P\x92.\xf7\xee#\x7f\xa8<d\xcc\r\xc3\x0f\x1a{j\x8d\xf4\xc1\x89>-a$\ta\xa4!j\xe84DMR\xe5\xe9\x8dq\x1f\x1a;g\xbed\x04{\xca\x0f\x1b{p\xee\xdd1\xdb\xfb\x0c\x90B\xf1Y\xb3\x1f\x8by_\xd7D\x1f\x82\xd9\xd3\x7f\\m\xac\xca\x0f\xe5\x99\x8b\x1d\xa7\x1a~\xba\xbf\x14\xa5\x17,\x14)\xf9\xdeZ\xf9R\xea\xf6\x1e\x19\xa75H\x12fI(I\xf5UR\x01\x98\xd6\xc4\xbe\x15\xadk\xa22^\x92\x840\xd2\x105t\x1a\xa2&e\xd9\xd3\xa9b\t\xb9\x83'\xd9\xa5j\xca\xf4\xa1\x9e\r\x97$--\xfam\xcc>\xc8\x99;e\xe2\xae\x0c\n\xf40\xd4\xfbd\x0b2\xac\xc9K\xe5\x1b\xab\x1d\xfbV\x19\xfb7\x93\xdb\x19{\xdeh\x19\xb4l\x86\xbc\x977\xcc\xb3\xdb.\xa4 \xd1\x9b\xfc\x88Hs\xebf\"\x9d\x89\x96$\x84\x91\x86\xa8\xa1\xd3\x105)\x93\xa7\x82\xf5R\x99v\xbc\xb0\xa3\xb5O\x10\x19\nC\x97k\xf6\xfb\xfa\xd7k\xb2\xac}P\x92>8\xf1\x91\xb1/\xdf\x92\x83*\xde}\xea\xbc\xb1\x9bu\xb8m\xec\x962\xb7\xe7\x07\n\xd1\xf1\xbb\xb0\x06\xa9\x86\xf0\x16\xc0\xdc\xde\xa5q\x89\x95!\x17\x8c4D\r\x9d\x86\xa8I\xaa<]\xc8\x97o\x9d\x96z\xad\x8d=\xee\xfd\x0e\xd6\xfe.\x19\xda\xbe\xe2\x92\xb5\xddU\r\x18\x04\xd7\xb7QX\x8c\xed\x9b@[-\xd7\xae\xdf\"\xdb\x17e7\x97\tL\xc4'I\xd9\x8e\x9f\x1d?Uv\\{\xd1>7\x99T\x18i\x88\x1a:\rQ\x13\x89\xef\x9epM\nqf\x19qzl,\x93\xa8:b\xcf\x98\\k:X\xc5\xd7\xad\x13\xfe\xbf\x97\x0e\xf6\x07\xf1xL_\xf6\x14\x05\x18i\x88\x1a:\rQ\x932y\xc2L\xaac\xa9dR(I\x18\x96}R\xe5\xc82\xb6\xcf\x11\x99\x1bUh_\x87r\x95I\xb8\xa4\n\xd7\x9e\\\x9f\xf4\x0e\xb9.\xdf\x8ba\xc1\xf9D\xe8\xe3{\x17/\xf6\xb9KQ\x93$\x84\x91\x86\xa8\xa1\xd3\x105\x91\xc8\x9eP\xaa<\xadTy\xf6>A\x08\"U\x1b\x0eHe\x1dnY\xbe\x14\xca\x15f\xed\xc0#5\x84\xf9[\xe5\x82'\x1f\x90-[\xbbz\xb7T\xcfy\xea\xd4\x1d\xc6n1\xb1^um\"`\xa4!j\xe84DMRw\x8d\xd0\x82YU\x10P\xe6|\x9b#\x01A*\xfa\\\xc5\xe7Z\xda\x96\xca1\x855\xb0K\xb9O\xaa\xba\xda\xa5*j\x92\xc4]#H(\xe84DMB\xb2\xa7\t\xb3\x87[\xdb_/*Q\x8d\xe3\xcb\xaa\x92\x88v\xf7\t\x97\x9c]\xcc\x97\x13u'U\x89<\xad\xf8\xab\xc8\x16J\x15\x12\x05Ir\xc1HC\xd4\xd0i\x88\x9a\xb8\xc9\x13J\x92K\x86\x82\xf4I\x04\x981\x05\xf96\xaaUK\xd9@\t7\\Bp\x1c\xd7\x06MH\xd1\xbaW\xac\xed\x95\xc3\xe4Z\x1c\xf3\xb5\x89\xb6\xde\xd1\x80\x91\x86\xa8\xa1\xd3\x105I]{BIJ\x95T\r\x19.;~\xbb\n\xd7Qn\x82H\x15\xe2\xea\xffx\xe1\x0c[\xf7F\t#\rQC\xa7!j\xe2&OQ\x90\x1e\\o\xc2\xcc(\xc8Z\x12\xee\xf8\x8d\xfb\x01\xa2T\xa1\x9c\xdd\xd5==f\x7fm\x16\xf6Z\xd1\xf1\x98\xcf\x19\x05\x18i\x88\x1a:\rQ\x93\x90\xec)\x99\x93{A$iW\x89|6\xfb\xcc\xb8\x07\x8c};S^\x1f7\x02\xda\rc\xe2YQK\xa6\xe4\x19\x1bw2?\xee\xc9\xee\x10.\x19\xd2faQ\x86\x91\x86\xa8\xa1\xd3\x105MO\x9f\x90\xca\xb1\xf6\xadu\x05\xcf\xc8\x9c\x95#c\xf6),\x90P_]\x19\xfb^8&^\xbb`\xe5\xe7\x8d\x1dd\xb2\x0eO\xd1\xc5] v\xd4J\xb9\x02J\x92K\x86\xfevT\n\xc5\xfd{\xf1\x89\xe9Z\xdb\n\"IA~\x93T\x81~\xc2HC\xd4\xd0i\x88\x9aP\xd9\x93K>\xb4\xbc0\xc7\xbe\x0b\xf7\xeec\xa7\x8c\x9d\xd7\xc3\xdeg\x97'\x99\x91\xfbH>\xe9\xef\x93\xa4M\x7f\x92k\xc7<bl\x94$\x1c\x07\xa5\xcd\xb5\x17\xdf\xbc\x82\x7f\x1a{A\x91\xc8h\x90\x82\xf6\xc6\x02#\rQC\xa7!j\xd4\xf2\x94\x08I\xea\xfbe9V\xef\xef5\xa7\xad\xfdo\xf5\x94c\x07\xbf\x98%\x87\xb6\xffy\xa3\x1c\xbc~x\xbfL\xe8\xad\xd9$\xd7N\x19\xa3+\x14\xf7K\xd2YG\xbbH\xd5\xe81\x9b\xad\xe3\x04\x91*\xb4\xb1\x0f^\x1b5\x18i\x88\x1a:\rQ\x13H\x9e\x12-IA\xc0L'33\xd3\xd8_\x19\xfbp\xcck\xd7\x80\x84\xd5\xd6\xd6\xc6\xec\xef:\x00=\x0c\xffKR\xc5HC\xd4\xd0i\x88\x9a\x84\x17\x96\x87\x91$D+I\x08\xf6\xc7q\x82H\x15\xe2\x92-\\\x0bsI\xc9\xb1\xba\x9f\x19\xbbW\xb6\x94gh\xcf\xa8\x8a\x02\x8c4D\r\x9d\x86\xa8I\x88<\x85\x91\xa4\xce\xcd\xe4\x98\xc20\x92\xe4\xc2%U\xaf\xbe4\xde\xd88q\xe7\x9a\xd0\xdb]+\x1b\xfc\x05\x91\xa4\x8a\n9\n\xfe\xe8\xd1\xa3\xd2\xe9Sb\xc6k3\xa5D\xc3HC\xd4\xd0i\x88\x9a@\xf2\x84\x13z\xf1\x9a\xe8\x0b\x03\xae7\x05\x91\xad \xfd]\x99\x91\xab=\xc8\x84\x1bJ\xd2\xa3#\xd7\xc8\x1f\xa0\xc8\x113/\x04\xbf\x9fZ\xb0 Z\x13}\x8c4D\r\x9d\x86\xa8\x89\xc4\x8e\xe5Z\xae\xf7\xfa\x92\xb1[8\xa4\x07%\t\xfb\x7f\xcd1\xa6\xff\x84\xdc\xf8\xe0\x93$\xc0U\x18\x8f\xdfgy\xde\x96\xb8?O\xbc`\xa4!j\xe84DM\xa3\x94'\xc4\x95\r\xf9\xda\xab\xec\xc7\x1d\"X}\xb7u\xd3Criu\xec\n\xbd \xb8\xb2$\x94$_\xf9D\x80\xf5\xacT\xc1HC\xd4\xd0i\x88\x9a\xb4\x1f\xcc\xac4\x07j\xf4\xe9\xab;P\xc35\xd1\x17\xafr\x88\x83\x95\x87\x8d]}\xec\x98\xb1\xc3\xacCaVU\xbc\xac\xfe\x13\x8f\xf3\xff\xc6\xa1\x83<P\x83\x84\x80NC\xd4\x84\x92'\xc4\xb5k\xc4\x1dG+\xac\xed\x88K\xc2\xce\x9e\x95\x90x\xbe\xae\xce\xd8Z\xa9BI\x1a\x94\x9b+c\x1e\xdck\xecE\x85u\x1eqCy\"\xa1\xa0\xd3\x105q\x9b\xdcs\x95I\xa0l\xe1\xb7KH^\x8f\xae\xc6N\xef;Hu_\x94\xb0\xce\x9d\xbbX\xdbI|a\xa4!j\xe84DM\xc2\xd7\x9eP\xb6\xee\x1bc\xcf\xb0\n!s\xf1mp\x94\xd9\xdd\xd2\xdb\xf3\xb2{\xf40\xf6\xder\xd9\xf0\x0e\xbfc\xc2\xa2q\xcc\x98Hx\x18i\x88\x1a:\rQ\x93\xd4\xd2\x88 \x85\xe8\x8b\x1cRU\xe6\xdb\x7fO\xb2-\\?B\xf9\xc3\xf6 \x19\x1c^\x9b\xaa\x82\xf9\xc6\x02#\rQC\xa7!j\"]\xb9\x87\xfb\xec!(UAd%P\x06GI\n\x0c#\rQC\xa7!j\"-O\x89\x90\x15\xcaPx\x18i\x88\x1a:\rQ\xe3\xab\xdc#$\x08\x8c4D\r\x9d\x86\xa8\xf97}\"\xaf\x8b'\x82\x81p\x00\x00\x00\x00IEND\xaeB`\x82"


async def test_generate_avatar(
    mock_aiohttp: aioresponses,
    snapshot: SnapshotAssertion,
    api_url: URL,
) -> None:
    """Test generation of avatar from user response."""
    # workaround due to qs double-encoding by aioresponses
    url = str(api_url / "api/v3/user") + "?userFields=preferences%2Citems%2Cstats"
    mock_aiohttp.get(url, body=load_fixture("user.json"))

    async with ClientSession() as session:
        habitica = Habitica(session, "test", "test")
        avatar = BytesIO()

        response = await habitica.generate_avatar(avatar, fmt="png")
        assert response == snapshot
        assert avatar.getvalue() == TEST_AVATAR


async def test_generate_avatar_to_file(
    mock_aiohttp: aioresponses,
    api_url: URL,
    tmp_path: pathlib.Path,
) -> None:
    """Test saving avatar to file."""
    # workaround due to qs double-encoding by aioresponses
    url = str(api_url / "api/v3/user") + "?userFields=preferences%2Citems%2Cstats"
    mock_aiohttp.get(url, body=load_fixture("user.json"))

    async with ClientSession() as session:
        habitica = Habitica(session, "test", "test")

        avatar = tmp_path / "avatar.png"

        await habitica.generate_avatar(str(avatar), fmt="png")
        await asyncio.sleep(0.1)  # wait a bit till saving avatar task settles
        loop = asyncio.get_running_loop()
        result = await loop.run_in_executor(None, avatar.read_bytes)
        assert result == TEST_AVATAR


@pytest.mark.parametrize(
    ("style_variations"),
    [
        "user_styles.json",
        "user_styles_with_chair.json",
        "user_styles_kickstarter.json",
        "user_styles_sleeping.json",
        "user_styles_spookySparkles.json",
        "user_styles_shinySeed.json",
        "user_styles_snowball.json",
        "user_styles_seafoam.json",
    ],
    ids=[
        "default",
        "with_chair",
        "kickstarter_backer_gear",
        "sleeping",
        "spookySparkles",
        "shinySeed",
        "snowball",
        "seafoam",
    ],
)
@pytest.mark.usefixtures("mock_aiohttp")
async def test_generate_avatar_from_styles(
    snapshot: SnapshotAssertion,
    style_variations: str,
) -> None:
    """Test generation of avatar from user styles."""

    user_styles = UserStyles.from_json(load_fixture(style_variations))
    async with ClientSession() as session:
        habitica = Habitica(session, "test", "test")
        avatar = BytesIO()

        response = await habitica.generate_avatar(avatar, user_styles, fmt="png")

        assert response == user_styles
        assert avatar.getvalue() == snapshot
