"""
QEMU Object Model testing tools.

usage: qom [-h] {set,get,list,tree,fuse} ...

Query and manipulate QOM data

optional arguments:
  -h, --help           show this help message and exit

QOM commands:
  {set,get,list,tree,fuse}
    set                Set a QOM property value
    get                Get a QOM property value
    list               List QOM properties at a given path
    tree               Show QOM tree from a given path
    fuse               Mount a QOM tree as a FUSE filesystem
"""
##
# Copyright John Snow 2020, for Red Hat, Inc.
# Copyright IBM, Corp. 2011
#
# Authors:
#  John Snow <jsnow@redhat.com>
#  Anthony Liguori <aliguori@amazon.com>
#
# This work is licensed under the terms of the GNU GPL, version 2 or later.
# See the COPYING file in the top-level directory.
#
# Based on ./scripts/qmp/qom-[set|get|tree|list]
##

import argparse

from qemu.qmp import ExecuteError

from .qom_common import QOMCommand


try:
    from .qom_fuse import QOMFuse
except ModuleNotFoundError as _err:
    if _err.name != 'fuse':
        raise
else:
    assert issubclass(QOMFuse, QOMCommand)


class QOMSet(QOMCommand):
    """
    QOM Command - Set a property to a given value.

    usage: qom-set [-h] [--socket SOCKET] <path>.<property> <value>

    Set a QOM property value

    positional arguments:
      <path>.<property>     QOM path and property, separated by a period '.'
      <value>               new QOM property value

    optional arguments:
      -h, --help            show this help message and exit
      --socket SOCKET, -s SOCKET
                            QMP socket path or address (addr:port). May also be
                            set via QMP_SOCKET environment variable.
    """
    name = 'set'
    help = 'Set a QOM property value'

    @classmethod
    def configure_parser(cls, parser: argparse.ArgumentParser) -> None:
        super().configure_parser(parser)
        cls.add_path_prop_arg(parser)
        parser.add_argument(
            'value',
            metavar='<value>',
            action='store',
            help='new QOM property value'
        )

    def __init__(self, args: argparse.Namespace):
        super().__init__(args)
        self.path, self.prop = args.path_prop.rsplit('.', 1)
        self.value = args.value

    def run(self) -> int:
        rsp = self.qmp.cmd(
            'qom-set',
            path=self.path,
            property=self.prop,
            value=self.value
        )
        print(rsp)
        return 0


class QOMGet(QOMCommand):
    """
    QOM Command - Get a property's current value.

    usage: qom-get [-h] [--socket SOCKET] <path>.<property>

    Get a QOM property value

    positional arguments:
      <path>.<property>     QOM path and property, separated by a period '.'

    optional arguments:
      -h, --help            show this help message and exit
      --socket SOCKET, -s SOCKET
                            QMP socket path or address (addr:port). May also be
                            set via QMP_SOCKET environment variable.
    """
    name = 'get'
    help = 'Get a QOM property value'

    @classmethod
    def configure_parser(cls, parser: argparse.ArgumentParser) -> None:
        super().configure_parser(parser)
        cls.add_path_prop_arg(parser)

    def __init__(self, args: argparse.Namespace):
        super().__init__(args)
        try:
            tmp = args.path_prop.rsplit('.', 1)
        except ValueError as err:
            raise ValueError('Invalid format for <path>.<property>') from err
        self.path = tmp[0]
        self.prop = tmp[1]

    def run(self) -> int:
        rsp = self.qmp.cmd(
            'qom-get',
            path=self.path,
            property=self.prop
        )
        if isinstance(rsp, dict):
            for key, value in rsp.items():
                print(f"{key}: {value}")
        else:
            print(rsp)
        return 0


class QOMList(QOMCommand):
    """
    QOM Command - List the properties at a given path.

    usage: qom-list [-h] [--socket SOCKET] <path>

    List QOM properties at a given path

    positional arguments:
      <path>                QOM path

    optional arguments:
      -h, --help            show this help message and exit
      --socket SOCKET, -s SOCKET
                            QMP socket path or address (addr:port). May also be
                            set via QMP_SOCKET environment variable.
    """
    name = 'list'
    help = 'List QOM properties at a given path'

    @classmethod
    def configure_parser(cls, parser: argparse.ArgumentParser) -> None:
        super().configure_parser(parser)
        parser.add_argument(
            'path',
            metavar='<path>',
            action='store',
            help='QOM path',
        )

    def __init__(self, args: argparse.Namespace):
        super().__init__(args)
        self.path = args.path

    def run(self) -> int:
        rsp = self.qom_list(self.path)
        for item in rsp:
            if item.child:
                print(f"{item.name}/")
            elif item.link:
                print(f"@{item.name}/")
            else:
                print(item.name)
        return 0


class QOMTree(QOMCommand):
    """
    QOM Command - Show the full tree below a given path.

    usage: qom-tree [-h] [--socket SOCKET] [<path>]

    Show QOM tree from a given path

    positional arguments:
      <path>                QOM path

    optional arguments:
      -h, --help            show this help message and exit
      --socket SOCKET, -s SOCKET
                            QMP socket path or address (addr:port). May also be
                            set via QMP_SOCKET environment variable.
    """
    name = 'tree'
    help = 'Show QOM tree from a given path'

    @classmethod
    def configure_parser(cls, parser: argparse.ArgumentParser) -> None:
        super().configure_parser(parser)
        parser.add_argument(
            'path',
            metavar='<path>',
            action='store',
            help='QOM path',
            nargs='?',
            default='/'
        )

    def __init__(self, args: argparse.Namespace):
        super().__init__(args)
        self.path = args.path

    def _list_node(self, path: str) -> None:
        print(path)
        items = self.qom_list(path)
        for item in items:
            if item.child:
                continue
            try:
                rsp = self.qmp.cmd('qom-get', path=path,
                                   property=item.name)
                print(f"  {item.name}: {rsp} ({item.type})")
            except ExecuteError as err:
                print(f"  {item.name}: <EXCEPTION: {err!s}> ({item.type})")
        print('')
        for item in items:
            if not item.child:
                continue
            if path == '/':
                path = ''
            self._list_node(f"{path}/{item.name}")

    def run(self) -> int:
        self._list_node(self.path)
        return 0


def main() -> int:
    """QOM script main entry point."""
    parser = argparse.ArgumentParser(
        description='Query and manipulate QOM data'
    )
    subparsers = parser.add_subparsers(
        title='QOM commands',
        dest='command'
    )

    for command in QOMCommand.__subclasses__():
        command.register(subparsers)

    args = parser.parse_args()

    if args.command is None:
        parser.error('Command not specified.')
        return 1

    cmd_class = args.cmd_class
    assert isinstance(cmd_class, type(QOMCommand))
    return cmd_class.command_runner(args)
