#!/usr/bin/env python3

import asyncio
import aiofiles
import json
import logging
import nio
import os
import signal
import stat
import time

import sys
assert sys.version_info >= (3, 5)

from presence import Presence

def handleInterrupt(sig, frame):
    global stop
    if os.getpid() == mainPid:
        logging.info( "Got stop signal." )
        stop = True
        for presence in presences:
            presence.stop()

async def main():
    client = nio.AsyncClient(config['server']['url'], config['server']['user'])

    try:
        await client.login(config['server']['password'])

        presence_tasks = []
        for presence in presences:
            presence_tasks.append( asyncio.create_task(presence.run(client)) )

        done, pending = await asyncio.wait( presence_tasks,
                                            return_when = asyncio.FIRST_EXCEPTION )

        for presence in presences:
            presence.stop()

        for task in done:
            try:
                task.result()
            except Exception as e:
                logging.error( "Error running task: %s" % str(e) )

    finally:
        logging.info("Closing client...")
        await client.close()

logging.basicConfig(format='[%(asctime)s] %(levelname)s: %(message)s',
                    level=logging.INFO,
                    datefmt='%m/%d/%Y %H:%M:%S')

mainPid = os.getpid()
signal.signal(signal.SIGINT, handleInterrupt)
signal.signal(signal.SIGTERM, handleInterrupt)

stop = False

if len(sys.argv) != 2:
    print("Usage: %s <config json>" % sys.argv[0])
    sys.exit(1)

with open(sys.argv[1]) as configFile:
    config = json.load(configFile)

fifo_dir = os.getenv('MTXBOT_FIFO_DIR', '/run/mtxbot')

while not stop:
    presences = []
    for entry in os.listdir(fifo_dir):
        fullpath = "%s/%s" % (fifo_dir, entry)
        if stat.S_ISFIFO(os.stat(fullpath).st_mode):
            logging.info("Creating presence for %s..." % entry)
            presences.append( Presence(entry, fullpath) )
    if len(presences) == 0:
        logging.error("No fifos could be found!")
        break
    asyncio.run(main())
    if not stop:
        logging.warning("Main loop exited!")
        logging.info("Restarting after grace period...")
        time.sleep(3.0)
