#!/usr/bin/python

# QEMU Guest Agent Client
#
# Copyright (C) 2012 Ryota Ozaki <ozaki.ryota@gmail.com>
#
# This work is licensed under the terms of the GNU GPL, version 2.  See
# the COPYING file in the top-level directory.
#
# Usage:
#
# Start QEMU with:
#
# # qemu [...] -chardev socket,path=/tmp/qga.sock,server,nowait,id=qga0 \
#   -device virtio-serial -device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0
#
# Run the script:
#
# $ qemu-ga-client --address=/tmp/qga.sock <command> [args...]
#
# or
#
# $ export QGA_CLIENT_ADDRESS=/tmp/qga.sock
# $ qemu-ga-client <command> [args...]
#
# For example:
#
# $ qemu-ga-client cat /etc/resolv.conf
# # Generated by NetworkManager
# nameserver 10.0.2.3
# $ qemu-ga-client fsfreeze status
# thawed
# $ qemu-ga-client fsfreeze freeze
# 2 filesystems frozen
#
# See also: https://wiki.qemu.org/Features/QAPI/GuestAgent
#

from __future__ import print_function
import base64
import random

import qmp


class QemuGuestAgent(qmp.QEMUMonitorProtocol):
    def __getattr__(self, name):
        def wrapper(**kwds):
            return self.command('guest-' + name.replace('_', '-'), **kwds)
        return wrapper


class QemuGuestAgentClient:
    error = QemuGuestAgent.error

    def __init__(self, address):
        self.qga = QemuGuestAgent(address)
        self.qga.connect(negotiate=False)

    def sync(self, timeout=3):
        # Avoid being blocked forever
        if not self.ping(timeout):
            raise EnvironmentError('Agent seems not alive')
        uid = random.randint(0, (1 << 32) - 1)
        while True:
            ret = self.qga.sync(id=uid)
            if isinstance(ret, int) and int(ret) == uid:
                break

    def __file_read_all(self, handle):
        eof = False
        data = ''
        while not eof:
            ret = self.qga.file_read(handle=handle, count=1024)
            _data = base64.b64decode(ret['buf-b64'])
            data += _data
            eof = ret['eof']
        return data

    def read(self, path):
        handle = self.qga.file_open(path=path)
        try:
            data = self.__file_read_all(handle)
        finally:
            self.qga.file_close(handle=handle)
        return data

    def info(self):
        info = self.qga.info()

        msgs = []
        msgs.append('version: ' + info['version'])
        msgs.append('supported_commands:')
        enabled = [c['name'] for c in info['supported_commands'] if c['enabled']]
        msgs.append('\tenabled: ' + ', '.join(enabled))
        disabled = [c['name'] for c in info['supported_commands'] if not c['enabled']]
        msgs.append('\tdisabled: ' + ', '.join(disabled))

        return '\n'.join(msgs)

    def __gen_ipv4_netmask(self, prefixlen):
        mask = int('1' * prefixlen + '0' * (32 - prefixlen), 2)
        return '.'.join([str(mask >> 24),
                         str((mask >> 16) & 0xff),
                         str((mask >> 8) & 0xff),
                         str(mask & 0xff)])

    def ifconfig(self):
        nifs = self.qga.network_get_interfaces()

        msgs = []
        for nif in nifs:
            msgs.append(nif['name'] + ':')
            if 'ip-addresses' in nif:
                for ipaddr in nif['ip-addresses']:
                    if ipaddr['ip-address-type'] == 'ipv4':
                        addr = ipaddr['ip-address']
                        mask = self.__gen_ipv4_netmask(int(ipaddr['prefix']))
                        msgs.append("\tinet %s  netmask %s" % (addr, mask))
                    elif ipaddr['ip-address-type'] == 'ipv6':
                        addr = ipaddr['ip-address']
                        prefix = ipaddr['prefix']
                        msgs.append("\tinet6 %s  prefixlen %s" % (addr, prefix))
            if nif['hardware-address'] != '00:00:00:00:00:00':
                msgs.append("\tether " + nif['hardware-address'])

        return '\n'.join(msgs)

    def ping(self, timeout):
        self.qga.settimeout(timeout)
        try:
            self.qga.ping()
        except self.qga.timeout:
            return False
        return True

    def fsfreeze(self, cmd):
        if cmd not in ['status', 'freeze', 'thaw']:
            raise Exception('Invalid command: ' + cmd)

        return getattr(self.qga, 'fsfreeze' + '_' + cmd)()

    def fstrim(self, minimum=0):
        return getattr(self.qga, 'fstrim')(minimum=minimum)

    def suspend(self, mode):
        if mode not in ['disk', 'ram', 'hybrid']:
            raise Exception('Invalid mode: ' + mode)

        try:
            getattr(self.qga, 'suspend' + '_' + mode)()
            # On error exception will raise
        except self.qga.timeout:
            # On success command will timed out
            return

    def shutdown(self, mode='powerdown'):
        if mode not in ['powerdown', 'halt', 'reboot']:
            raise Exception('Invalid mode: ' + mode)

        try:
            self.qga.shutdown(mode=mode)
        except self.qga.timeout:
            return


def _cmd_cat(client, args):
    if len(args) != 1:
        print('Invalid argument')
        print('Usage: cat <file>')
        sys.exit(1)
    print(client.read(args[0]))


def _cmd_fsfreeze(client, args):
    usage = 'Usage: fsfreeze status|freeze|thaw'
    if len(args) != 1:
        print('Invalid argument')
        print(usage)
        sys.exit(1)
    if args[0] not in ['status', 'freeze', 'thaw']:
        print('Invalid command: ' + args[0])
        print(usage)
        sys.exit(1)
    cmd = args[0]
    ret = client.fsfreeze(cmd)
    if cmd == 'status':
        print(ret)
    elif cmd == 'freeze':
        print("%d filesystems frozen" % ret)
    else:
        print("%d filesystems thawed" % ret)


def _cmd_fstrim(client, args):
    if len(args) == 0:
        minimum = 0
    else:
        minimum = int(args[0])
    print(client.fstrim(minimum))


def _cmd_ifconfig(client, args):
    print(client.ifconfig())


def _cmd_info(client, args):
    print(client.info())


def _cmd_ping(client, args):
    if len(args) == 0:
        timeout = 3
    else:
        timeout = float(args[0])
    alive = client.ping(timeout)
    if not alive:
        print("Not responded in %s sec" % args[0])
        sys.exit(1)


def _cmd_suspend(client, args):
    usage = 'Usage: suspend disk|ram|hybrid'
    if len(args) != 1:
        print('Less argument')
        print(usage)
        sys.exit(1)
    if args[0] not in ['disk', 'ram', 'hybrid']:
        print('Invalid command: ' + args[0])
        print(usage)
        sys.exit(1)
    client.suspend(args[0])


def _cmd_shutdown(client, args):
    client.shutdown()
_cmd_powerdown = _cmd_shutdown


def _cmd_halt(client, args):
    client.shutdown('halt')


def _cmd_reboot(client, args):
    client.shutdown('reboot')


commands = [m.replace('_cmd_', '') for m in dir() if '_cmd_' in m]


def main(address, cmd, args):
    if not os.path.exists(address):
        print('%s not found' % address)
        sys.exit(1)

    if cmd not in commands:
        print('Invalid command: ' + cmd)
        print('Available commands: ' + ', '.join(commands))
        sys.exit(1)

    try:
        client = QemuGuestAgentClient(address)
    except QemuGuestAgent.error as e:
        import errno

        print(e)
        if e.errno == errno.ECONNREFUSED:
            print('Hint: qemu is not running?')
        sys.exit(1)

    if cmd == 'fsfreeze' and args[0] == 'freeze':
        client.sync(60)
    elif cmd != 'ping':
        client.sync()

    globals()['_cmd_' + cmd](client, args)


if __name__ == '__main__':
    import sys
    import os
    import optparse

    address = os.environ['QGA_CLIENT_ADDRESS'] if 'QGA_CLIENT_ADDRESS' in os.environ else None

    usage = "%prog [--address=<unix_path>|<ipv4_address>] <command> [args...]\n"
    usage += '<command>: ' + ', '.join(commands)
    parser = optparse.OptionParser(usage=usage)
    parser.add_option('--address', action='store', type='string',
                      default=address, help='Specify a ip:port pair or a unix socket path')
    options, args = parser.parse_args()

    address = options.address
    if address is None:
        parser.error('address is not specified')
        sys.exit(1)

    if len(args) == 0:
        parser.error('Less argument')
        sys.exit(1)

    main(address, args[0], args[1:])
