#!/usr/bin/env python3
import sys
import os
import time
import subprocess
import atexit
import json

BASE_DIR = os.path.realpath(os.path.dirname(__file__) + "/..")

def prepare():
    manage_py = os.path.join(BASE_DIR, 'api/manage.py')

    # Require EMBLEM_ENV to be set
    emblem_env = os.environ.get("EMBLEM_ENV")
    if not emblem_env:
        print("ERROR: EMBLEM_ENV environment variable is not set", file=sys.stderr)
        sys.exit(1)

    # Run migrations, create cache table, and send alert
    em = ['sendalert', f"emblem {emblem_env} started"]
    for subcmd in [['migrate'], ['createcachetable'], em]:
        cmd = [manage_py] + subcmd
        subprocess.check_call(cmd)

def main():
    prepare()
    subprocess.check_output(['ls', '/emblem/web/dist/index.html'])
    print("Moving nginx.conf to /etc");
    subprocess.check_output(['mv', '/emblem/nginx.conf', '/etc/nginx/nginx.conf'])
    subprocess.check_output(['nginx', '-t'])
    nginx = subprocess.Popen(['nginx'])
    gunicorn_args = os.environ.get("GUNICORN_ARGS", "").split()
    gunicorn_log = '/emblem/log/gunicorn.log'
    subprocess.check_output(['touch', gunicorn_log])

    # Use tee to write logs to both file and stderr
    tee = subprocess.Popen(['tee', '-a', gunicorn_log],
                          stdin=subprocess.PIPE,
                          stdout=sys.stderr)

    gunicorn = subprocess.Popen(['gunicorn',
        '-b', '127.0.0.1:28266',
        '-b', 'unix:/tmp/gunicorn.sock',
        '--log-level=info',
        '--access-logfile=-',  # Log to stdout
        '--error-logfile=-',   # Log to stdout
        '-w', '8',
        '-t', '0',
        'emblemapi.wsgi:application'
        ] + gunicorn_args,
        cwd=os.path.join(BASE_DIR, 'api'),
        stdout=tee.stdin,
        stderr=subprocess.STDOUT)

    procs = [nginx, gunicorn, tee]
    atexit.register(lambda: [x.kill() for x in procs])

    print("Started nginx and gunicorn, entering infinite loop")
    while True:
        for x in procs:
            if x.poll() != None:
                print(f"{x.args} exited, code: {x.returncode}")
                sys.exit(1)
        time.sleep(1)

sys.exit(main())
