import eventlet
import os
import sys

from st2actions import config
from st2actions import scheduler, worker
from st2common import log as logging
from st2common.service_setup import setup as common_setup
from st2common.service_setup import teardown as common_teardown

LOG = logging.getLogger(__name__)


eventlet.monkey_patch(
    os=True,
    select=True,
    socket=True,
    thread=False if '--use-debugger' in sys.argv else True,
    time=True)


def _setup():
    common_setup(service='actionrunner', config=config, setup_db=True, register_mq_exchanges=True,
                 register_signal_handlers=True)


def _run_worker():
    LOG.info('(PID=%s) Worker started.', os.getpid())

    components = [
        scheduler.get_scheduler(),
        worker.get_worker()
    ]

    try:
        for component in components:
            component.start()

        for component in components:
            component.wait()
    except (KeyboardInterrupt, SystemExit):
        LOG.info('(PID=%s) Worker stopped.', os.getpid())

        errors = False

        for component in components:
            try:
                component.shutdown()
            except:
                LOG.exception('Unable to shutdown %s.', component.__class__.__name__)
                errors = True

        if errors:
            return 1
    except:
        LOG.exception('(PID=%s) Worker unexpectedly stopped.', os.getpid())
        return 1

    return 0


def _teardown():
    common_teardown()


def main():
    try:
        _setup()
        return _run_worker()
    except SystemExit as exit_code:
        sys.exit(exit_code)
    except:
        LOG.exception('(PID=%s) Worker quit due to exception.', os.getpid())
        return 1
    finally:
        _teardown()
