import unittest
import asyncio

import sys
import logging
logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(asctime)s %(name)s %(levelname)s: %(message)s')
logger = logging.getLogger(__name__)

from src.millconnect import backend
from src.millconnect.server import listen, getAuthentificationToken

import requests
from pathlib import Path

class BackendTest(unittest.IsolatedAsyncioTestCase):

    def test_availableHost(self):
        availableHost = backend.getAvailableHost()
        self.assertIsNotNone(availableHost)

    async def test_authorization(self):
        async def handleAuthorization(websocket, running):
            token = await getAuthentificationToken(websocket)
            logger.info(f'Got token: {token}')

            username = backend.whoAmI('http://zahnomat-backend:8000', token)
            logger.info(username.json())
            running.set_result(False)

        running = asyncio.get_running_loop().create_future()
        server = await listen('localhost', 8765, lambda x: handleAuthorization(x, running))
        logger.info('Started server')

        await running

    async def test_orderCreation(self):
        async def handleOrderCreation(websocket, running):
            token = await getAuthentificationToken(websocket)
            logger.info(f'Got token: {token}')

            host = 'http://zahnomat-backend:8000'

            orderData = {
                'projectName': 'Test project',
                'deliveryType': 1,
                'comment': 'Some comment',
                'creationMethod': 'millConnect',
                'fastline': True,
                'alternativeDeliveryAddress': None
            }
            headers = {
                'Authorization': f'Token {token}',
            }
            response = requests.post(f'{host}/v1/orders/', json=orderData, headers=headers)

            running.set_result(False)
            self.assertEqual(response.status_code, 201)


        running = asyncio.get_running_loop().create_future()
        server = await listen('localhost', 8765, lambda x: handleOrderCreation(x, running))
        logger.info('Started server')

        await running

    async def test_elementCreation(self):
        async def handleOrderCreation(websocket, running):
            token = await getAuthentificationToken(websocket)
            logger.info(f'Got token: {token}')

            host = 'http://zahnomat-backend:8000'

            orderData = {
                'projectName': 'Test project',
                'deliveryType': 1,
                'comment': 'Some comment',
                'creationMethod': 'millConnect',
                'fastline': True,
                'alternativeDeliveryAddress': None
            }
            headers = {
                'Authorization': f'Token {token}',
            }
            response = requests.post(f'{host}/v1/orders/', json=orderData, headers=headers)
            self.assertEqual(response.status_code, 201)
            newOrder = response.json()

            elementData = {
                'type': 1,
                'material': 1,
                'color': 1,
                'comment': 'some comment',
            }
            files = {
                'file': open('tests/samples/86208/1135-gold_-2018-11-28-36-crown_cad.stl', 'rb')
            }
            response = requests.post(f'{host}/v1/orders/{newOrder['id']}/elements/',files=files, data=elementData, headers=headers)
            self.assertEqual(response.status_code, 201)

            running.set_result(False)

        while True:

            running = asyncio.get_running_loop().create_future()
            server = await listen('localhost', 8765, lambda x: handleOrderCreation(x, running))
            logger.info('Started server')

            try:
                await running
                server.close()
            except KeyboardInterrupt:
                break

    async def test_clientVersion(self):
        async def handleOrderCreation(websocket, running):
            token = await getAuthentificationToken(websocket)
            logger.info(f'Got token: {token}')

            host = 'http://zahnomat-backend:8000'

            version = backend._getVersion(host, token)
            print(version)

            running.set_result(False)

        while True:

            running = asyncio.get_running_loop().create_future()
            server = await listen('localhost', 8765, lambda x: handleOrderCreation(x, running))
            logger.info('Started server')

            try:
                await running
                server.close()
            except KeyboardInterrupt:
                break

    async def test_downloadClient(self):
        async def handleOrderCreation(websocket, running):
            token = await getAuthentificationToken(websocket)
            logger.info(f'Got token: {token}')

            host = 'http://zahnomat-backend:8000'

            currentVersion = '0.0.1rc0'
            newFile = backend.downloadClient(host, token, currentVersion, Path('./'))
            self.assertTrue(newFile.exists())

            newFile.unlink()

            running.set_result(False)

        while True:

            running = asyncio.get_running_loop().create_future()
            server = await listen('localhost', 8765, lambda x: handleOrderCreation(x, running))
            logger.info('Started server')

            try:
                await running
                server.close()
            except KeyboardInterrupt:
                break