#!/usr/bin/python3 -sP
#
# Copyright (c) 2013-2015 Marin Atanasov Nikolov <dnaeon@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer
#    in this position and unchanged.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""
vpoller-worker is a daemon, which receives new message requests from a
ZeroMQ proxy/broker that need to be processed.

The received messages are dispatched to the internal vSphere Agents for
performing the actual polling from a vCenter server.

"""

from __future__ import print_function

import os
import logging

from vpoller import __version__
from vpoller.client import VPollerClient
from vpoller.worker import VPollerWorkerManager
from docopt import docopt

def start(config, concurrency):
    """
    Start the vPoller Worker

    Args:
        config      (str): Path to the vPoller configuration file
        concurrency (int): Number of Worker processes to start

    """
    if not concurrency:
        concurrency = 0

    manager = VPollerWorkerManager(
        config_file=config,
        num_workers=int(concurrency)
    )
    manager.start()

def stop(endpoint):
    """
    Stops the vPoller Worker

    Args:
        endpoint (string): The endpoint we send the shutdown message to

    """
    client = VPollerClient(endpoint=endpoint, timeout=1000, retries=3)
    result = client.run({'method': 'shutdown'})

    print(result.encode('utf-8'))

def status(endpoint):
    """
    Get status information from the vPoller Worker

    Args:
        endpoint (string): The endpoint we send the status request to
    
    """
    client = VPollerClient(endpoint=endpoint, timeout=1000, retries=3)
    result = client.run({'method': 'status'})

    print(result.encode('utf-8'))

def main():
    usage="""
Usage: vpoller-worker [-d] [-c <concurrency>] [-f <config>] start
       vpoller-worker [-d] -e <endpoint> stop
       vpoller-worker [-d] -e <endpoint> status
       vpoller-worker --help
       vpoller-worker --version

Arguments:
  start                                          Start the VPoller Worker
  stop                                           Stop the VPoller Worker
  status                                         Get status information

Options:
  -h, --help                                     Display this usage info
  -v, --version                                  Display version and exit
  -d, --debug                                    Debug mode, be more verbose
  -c <concurrency>, --concurrency <concurrency>  The number of worker processes to be created.
                                                 The default is the number of CPUs available on
                                                 the system.
  -f <config>, --file <config>                   Specify config file to use
                                                 [default: /etc/vpoller/vpoller.conf]
  -e <endpoint>, --endpoint <endpoint>           Specify the endpoint we connect to

"""

    args = docopt(usage, version=__version__)

    if not os.path.exists(args['--file']):
        raise SystemExit('Configuration file {} does not exist'.format(args['--file']))

    level = logging.DEBUG if args['--debug'] else logging.INFO
    logging.basicConfig(
        format='[%(asctime)s - %(levelname)s/%(processName)s] %(message)s',
        level=level
    )

    if args['start']:
        start(
            config=args['--file'],
            concurrency=args['--concurrency']
        )
    elif args['stop']:
        stop(args['--endpoint'])
    elif args['status']:
        status(args['--endpoint'])

if __name__ == '__main__':
    main()

