#!/usr/bin/env python
"""Script to run infobase.

USAGE:

* Run Infobase http server at port 7070.

    $ python ./scripts/infobase-server infobase.yml 7070

* Run Infobase as fastcgi server at port 7070

    $ python ./scripts/infobase-server infobase.yml fastcgi 7070
"""

import logging
import os
import sys

import _init_path  # noqa: F401  Imported for its side effect of setting PYTHONPATH
import web

from openlibrary.utils.sentry import Sentry

logger = logging.getLogger("openlibrary." + __file__)


def setup_env():
    # make sure PYTHON_EGG_CACHE is writable
    os.environ['PYTHON_EGG_CACHE'] = "/tmp/.python-eggs"

    # required when run as fastcgi
    os.environ['REAL_SCRIPT_NAME'] = ""


def main(args):
    if len(args) < 1 or args[0] in ['-h', '--help']:
        print("USAGE: %s configfile [port]" % (sys.argv[0]), file=sys.stderr)
        sys.exit(1)

    start(*args)


def start(config_file, *args):
    from infogami.infobase import server

    server.load_config(config_file)

    sentry = Sentry(getattr(server.config, 'sentry', {}))
    if sentry.enabled:
        sentry.init()
        sentry.bind_to_webpy_app(server.app)

    # remove config from command line args
    sys.argv = [sys.argv[0]] + list(args)

    # The web.py runfcgi is using multiplexed=True option for fastcgi server
    # and that seem to cause some memory leaks. Using a variant of runfcgi
    # that sets multiplexed=False.
    if 'fastcgi' in sys.argv:
        sys.argv.remove('fastcgi')
        args = sys.argv[1:]

        wsgifunc = server.app.wsgifunc()
        if args:
            return runfcgi(wsgifunc, web.validaddr(args[0]))
        else:
            return runfcgi(wsgifunc, None)
    else:
        server.run()


def runfcgi(func, addr=('localhost', 8000)):
    """Runs a WSGI function as a FastCGI server."""
    import flup.server.fcgi as flups

    # Start fcgi server with multiplexed=False
    # Noticed memory leaks when running with multiplexed=True.
    logger.info(f"flups.WSGIServer({func}, bindAddress={addr})")
    return flups.WSGIServer(
        func, multiplexed=False, bindAddress=addr, debug=False
    ).run()


def start_gunicorn_server():
    """Starts the infobase server using gunicorn server."""
    from gunicorn.app.base import Application

    configfile = sys.argv.pop(1)

    class WSGIServer(Application):
        def init(self, parser, opts, args):
            pass

        def load(self):
            from infogami.infobase import server

            server.load_config(configfile)
            return server.app.wsgifunc()

    WSGIServer("%prog infobase.yml --gunicorn [options]").run()


if __name__ == "__main__":
    setup_env()

    if "--gunicorn" in sys.argv:
        sys.argv.pop(sys.argv.index("--gunicorn"))
        start_gunicorn_server()
    else:
        main(sys.argv[1:])
