'''
CloudControl VM related commands
'''

from cccli.exception import *
from sjrpc.core.exceptions import *
from cccli.printer import Printer, color
from cccli.command import TqlCommand

class Command_start(TqlCommand):
    '''Start a stopped vm'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.tql_filter += "&r=vm&status=stopped"

    def __call__(self, argv):
        # arg parse
        self.parse_args(argv)
        if len(self.args) != 1:
            raise cmdBadArgument()
        # rpc call
        self.rpccall("start", self.args[0])

    def remote_functions(self):
        return set(("start",))


class Command_stop(TqlCommand):
    '''Stop a running vm'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.tql_filter += "&r=vm&status=running"

    def __call__(self, argv):
        # arg parse
        self.parse_args(argv)
        if len(self.args) != 1:
            raise cmdBadArgument()
        # rpc call
        self.rpccall("stop", self.args[0])

    def remote_functions(self):
        return set(("stop",))


class Command_destroy(TqlCommand):
    '''Force a vm to stop'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.tql_filter += "&r=vm&status!=stopped"

    def __call__(self, argv):
        # arg parse
        self.parse_args(argv)
        if len(self.args) != 1:
            raise cmdBadArgument()
        # rpc call
        self.rpccall("destroy", self.args[0])

    def remote_functions(self):
        return set(("destroy",))


class Command_pause(TqlCommand):
    '''Pause a running vm'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.tql_filter += "&r=vm&status=stopped"

    def __call__(self, argv):
        # arg parse
        self.parse_args(argv)
        if len(self.args) != 1:
            raise cmdBadArgument()
        # rpc call
        self.rpccall("pause", self.args[0])

    def remote_functions(self):
        return set(("pause",))


class Command_resume(TqlCommand):
    '''Resume a paused vm'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.tql_filter += "&r=vm&status=paused"

    def __call__(self, argv):
        # arg parse
        self.parse_args(argv)
        if len(self.args) != 1:
            raise cmdBadArgument()
        # rpc call
        self.rpccall("resume", self.args[0])

    def remote_functions(self):
        return set(("resume",))

class Command_undefine(TqlCommand):
    '''Undefine a stopped vm'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.tql_filter += "&r=vm&status=stopped"
        self.add_option("-k", "--keep-storage", action="store_false", dest="clean", default=True,
                        help="Remove vm storage")

    def __call__(self, argv):
        # arg parse
        self.parse_args(argv)
        if len(self.args) != 1:
            raise cmdBadArgument()
        # rpc call
        self.rpccall("undefine", self.args[0], self.options.clean)

    def remote_functions(self):
        return set(("undefine",))

class Command_clone(TqlCommand):
    '''Clone vm'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.set_usage("%prog [options] <source tql> <dest tql> <name>")

    def __call__(self, argv):
        # Parse argline
        self.parse_args(argv)
        # Check args count
        if len(self.args) != 3:
            raise cmdBadArgument()
        stql = self.args[0]
        dtql = self.args[1]
        newname = self.args[2]
        if self.options.direct:
            self.rpccall("clone", stql, dtql, newname)
        else:
            # list stql
            self.printer.out("<= Source VM:")
            if not self.options.raw:
                self.tql_filter = "&r=vm$status"
            o = self.rpccall("list", stql, _direct=True, _status=True)
            if len(o["objects"]) != 1:
                raise cmdError("You must select only one VM")
            # list dtql
            self.printer.out("=> Destination HV:")
            if not self.options.raw:
                self.tql_filter = "&r=hv$nvm"
            o = self.rpccall("list", dtql, _direct=True, _status=True)
            if len(o["objects"]) != 1:
                raise cmdError("You must select only one HV")
            # check if destination vm does not exist
            o = self.rpccall("list", "%s&h:%s"%(dtql,newname), _direct=True, _status=False)
            if not self.options.raw:
                self.tql_filter = "&r=vm"
            if len(o["objects"]) != 0:
                raise cmdError("Destination VM exist on HV")
            # ask confirmation
            if self.printer.ask("Do you confirm? (I'm god) ") != "I'm god":
                raise cmdWarning("User resign")
            # run migration
            self.tql_filter = ""
            self.rpccall("clone", stql, dtql, newname, _direct=True)

    def remote_functions(self):
        return set(("clone",))