#!python

import argparse
import json
import os
import re
import sys
import yaml

from platypush import parse_config_file
from platypush.backend.kafka import KafkaBackend
from platypush.backend.local import LocalBackend
from platypush.backend.pushbullet import PushbulletBackend


def print_usage():
    print ('''Usage: {} [-h|--help] <-t|--target <target name>> <-a|--action <action name>> payload
    -h, --help:\t\tShow this help and exit
    -b, --backend:\tBackend to deliver the message [pushbullet|kafka] (default: whatever specified in your config with pusher=True)
    -t, --target:\tName of the target device/host
    -a, --action\tAction to run, it includes both the package name and the method (e.g. shell.exec or music.mpd.play)
    payload:\t\tArguments to the action
'''.format(sys.argv[0]))

def get_pb_device_by_name(pb, name):
    devices = [
        _ for _ in pb.devices if _.nickname == name
    ]

    return devices[0] if devices else None

def get_backend(config):
    if 'backend.local' in config \
            and 'pusher' in config['backend.local'] \
            and config['backend.local']['pusher']:
        c = config['backend.local']
        return LocalBackend({'fifo': c['fifo']})
    elif 'backend.pushbullet' in config \
            and 'pusher' in config['backend.pushbullet'] \
            and config['backend.pushbullet']['pusher']:
        c = config['backend.pushbullet']
        return PushbulletBackend({'token':c['token'], 'device':c['device']})
    elif 'backend.kafka' in config \
            and 'pusher' in config['backend.kafka'] \
            and config['backend.kafka']['pusher']:
        c = config['backend.kafka']
        return KafkaBackend({'server':c['server'], 'topic':c['topic']})

def main():
    config = parse_config_file()

    parser = argparse.ArgumentParser()
    parser.add_argument('--target', '-t', dest='target', required=True,
                        help="Destination of the command")

    parser.add_argument('--action', '-a', dest='action', required=True,
                        help="Action to execute, as package.method")

    parser.add_argument('--backend', '-b', dest='backend', required=False,
                        help="Backend to deliver the message " +
                        "[pushbullet|kafka|local] (default: whatever " +
                        "specified in your config with pusher=True)")

    opts, args = parser.parse_known_args(sys.argv[1:])
    payload = {}

    if len(args) % 2 != 0:
        raise RuntimeError('Odd number of key-value options passed: {}'.
                           format(args))

    if opts.target == 'localhost' and 'backend.local' in config:
        cfg = config['backend.local']
        cfg['pusher'] = True
        config = { 'backend.local': cfg }

    if opts.backend:
        backend_cfg_name = 'backend.' + opts.backend
        if backend_cfg_name not in config:
            raise RuntimeError('{} backend specified, but no configuration ' +
                               'for it available'.format(backend_cfg_name))

        cfg = config[backend_cfg_name]
        cfg['pusher'] = True
        config = { backend_cfg_name: cfg }

    backend = get_backend(config)

    for i in range(0, len(args), 2):
        payload[re.sub('^-+', '', args[i])] = args[i+1]

    msg = {
        'target': opts.target,
        'action': opts.action,
        **payload,
    }

    print('msg: {}'.format(msg))

    backend.send_msg(msg)

if __name__ == '__main__':
    main()

# vim:sw=4:ts=4:et:

