#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import click
import sys
import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent


# fmt: off
@click.command()
@click.option('--name', '-n',
                            default=None,
                            type=str,
                            help="Onion Service Name")
@click.option('--onion-domain', '-od',
                            default=None,
                            type=str,
                            help="Onion domain where TCS will be published")
@click.option('--dev',
                            default=False,
                            type=bool,
                            help="Run in development mode (Default: 0)")
@click.option('--debug',
                            default=False,
                            type=bool,
                            help="Run in debug mode (--dev must be true) (Default: 0)")
# fmt: on
def main(name, onion_domain, dev, debug):
    if not name:
        click.echo("Error: You must specify a name.")
        click.echo(f"run {sys.argv[0]} --help for more info.")
        sys.exit(1)

    if not onion_domain:
        click.echo("Error: Onion domain is required")
        click.echo(f"run {sys.argv[0]} --help for more info.")
        sys.exit(1)

    instance_name = name
    os.environ["INSTANCE_NAME"] = instance_name
    os.environ["ONION_DOMAIN"] = onion_domain

    if os.path.exists(BASE_DIR / f"pid/{instance_name}.pid"):
        click.echo(
            'Error: Another instance is already using name "%s"' % instance_name
        )
        sys.exit(1)

    print("> Clean database")
    clean_database(instance_name)

    print("> Run server")
    run_webserver(instance_name=instance_name, dev=dev)


def clean_database(instance_name):
    """Remove old database and create new one"""
    try:
        os.remove(BASE_DIR / f"db/{instance_name}.sqlite3")
    except:  # noqa
        pass

    # Call models.py function to create database
    from chatsecure.models import init_db
    init_db()


def run_webserver(instance_name, dev=True):
    if dev:
        from chatsecure.app import create_app, socketio
        # Dev
        app = create_app(debug=dev)
        socketio.run(app, host="0.0.0.0", port=5000)
        sys.exit()
    else:
        # Production
        import eventlet
        import socket
        import signal

        def stop_webserver(signum, frame):
            # Remove database at exit
            os.remove(BASE_DIR / f"db/{instance_name}.db")
            os.remove(BASE_DIR / f"db/{instance_name}.db-shm")
            os.remove(BASE_DIR / f"db/{instance_name}.db-wal")

            # Remove pid file
            os.remove(BASE_DIR / f"pid/{instance_name}.pid")

            # Remove unix socket
            os.remove(f"/var/run/tcs_{instance_name}.sock")
            # os.remove(f"/tmp/tcs_{instance_name}.sock")  # dev

            sys.exit()

        signal.signal(signal.SIGTERM, stop_webserver)

        # Create pid file
        pidfile = open(BASE_DIR / f"pid/{instance_name}.pid", "w+")
        pidfile.write("%s" % os.getpid())
        pidfile.close()

        # Unix socket file path
        socket_path = f"/var/run/tcs_{instance_name}.sock"
        # socket_path = f"/tmp/tcs_{instance_name}.sock"  # dev

        green_sock = eventlet.listen(socket_path, family=socket.AF_UNIX)
        os.chmod(socket_path, 0o777)

        from chatsecure.wsgi import app
        eventlet.wsgi.server(
                sock=green_sock,
                site=app
            )

    sys.exit()


if __name__ == "__main__":
    main()
