# Copyright 3D Control Systems, Inc. All Rights Reserved 2017-2019.
# Built in San Francisco.

# This software is distributed under a commercial license for personal,
# educational, corporate or any other use.
# The software as a whole or any parts of it is prohibited for distribution or
# use without obtaining a license from 3D Control Systems, Inc.

# All software licenses are subject to the 3DPrinterOS terms of use
# (available at https://www.3dprinteros.com/terms-and-conditions/),
# and privacy policy (available at https://www.3dprinteros.com/privacy-policy/)

import aiohttp
import aiohttp.web

import event_handler_bridge
import web_interface.auth
import web_interface.printers_html
import web_interface.api2_handler


class WSHandlerBridge(event_handler_bridge.EventHandlerBridge):

    def wrap_data(self, data):
        return {'type': 'event', 'data': data}

    async def websock_handler(self, request):
        web_interface.auth.check_auth(request)
        self.logger.info('UI websocket connection from: ' + str(request.remote))
        ws = aiohttp.web.WebSocketResponse(timeout=0.5, compress=False)
        await ws.prepare(request)
        self.connections.append(ws)
        async for msg in ws:
            if self.app.stop_flag or self.stop_flag:
                break
            if msg.type == aiohttp.WSMsgType.TEXT:
                #  self.logger.debug("UI websocket %s received: %s", (str(request.remote), msg.data))
                if msg.data == 'close':
                    break
                elif msg.data == 'get_printers_html':
                    await ws.send_json({'type': 'printers_html', 'data': web_interface.printers_html.get_printers_html(request)})
                elif msg.data == 'get_printers_json':
                    await ws.send_json({'type': 'printers_json', 'data': web_interface.api2_handler.printers_report(self.app)})
                elif msg.data == 'get_update_availability':
                    await ws.send_json({'type': 'update_available', 'data': self.app.updater.update_available})
                else:
                    await ws.send_json({'type': 'error', 'data': 'unknown ws request type: ' + str(msg.data)})
            elif msg.type == aiohttp.WSMsgType.ERROR:
                self.logger.warning('UI websocket connection closed with exception %s', ws.exception())
                break
            elif msg.type == aiohttp.WSMsgType.CLOSED:
                self.logger.debug("UI websocket %s got closed frame", str(request.remote))
                break
        self.connections.remove(ws)
        await ws.write_eof()
        self.logger.info('UI websocket disconnect. Remote: ' + str(request.remote))
        return ws

    def close(self):
        self.stop_flag = True
