import asyncio
import json
import logging
import os

import aiohttp_cors
from aiohttp import web
from aiortc import MediaStreamTrack, RTCPeerConnection, RTCSessionDescription, RTCConfiguration, RTCRtpCodecCapability
from aiortc.contrib.media import MediaBlackhole, MediaPlayer, MediaRecorder, MediaRelay

ROOT = os.path.dirname(__file__)

web.WebSocketResponse()
logger = logging.getLogger(__name__)

pcs = set()


async def offer(request):
    params = await request.json_str()
    offer = RTCSessionDescription(sdp=params["sdp"], type=params["type"])
    pc = RTCPeerConnection(RTCConfiguration([]))
    pcs.add(pc)
    player = MediaPlayer(os.path.join(ROOT, "demo-instruct.wav"))
    rc = pc.addTransceiver(player.video, 'sendonly')
    rc.setCodecPreferences([RTCRtpCodecCapability(mimeType='video/H264',
                                                  clockRate=90000,
                                                  channels=None,
                                                  parameters={
                                                      'level-asymmetry-allowed': '1',
                                                      'packetization-mode': '1',
                                                      'profile-level-id': '42e01f'
                                                  })])
    await pc.setRemoteDescription(offer)
    answer = await pc.createAnswer()
    await pc.setLocalDescription(answer)
    return web.Response(
        content_type="application/json",
        text=json.dumps(
            {"sdp": pc.localDescription.sdp, "type": pc.localDescription.type}
        ),
    )


async def on_shutdown(app):
    # close peer connections
    coros = [pc.close() for pc in pcs]
    await asyncio.gather(*coros)
    pcs.clear()


if __name__ == '__main__':
    app = web.Application()
    app.on_shutdown.append(on_shutdown)
    app.router.add_post("/offer", offer)

    cors = aiohttp_cors.setup(app, defaults={
        "*": aiohttp_cors.ResourceOptions(
            allow_credentials=True,
            expose_headers="*",
            allow_headers="*"
        )
    })

    for route in list(app.router.routes()):
        cors.add(route)
    web.run_app(
        app, access_log=None, host='0.0.0.0', port=8081
    )
