import uuid
import os

from uncloud.host.virtualmachine import create_vxlan_br_tap
from uncloud.oneshot import logger

class VM(object):
    def __init__(self, vmm, config):
        self.config = config
        self.vmm = vmm

        # Extract VM specs/metadata from configuration.
        self.name         = config.get('name', 'no-name')
        self.memory       = config.get('memory', 1024)
        self.cores        = config.get('cores', 1)
        self.threads      = config.get('threads', 1)
        self.image_format = config.get('image_format', 'qcow2')
        self.image        = config.get('image')
        self.uuid         = config.get('uuid', str(uuid.uuid4()))
        self.mac          = config.get('mac')
        self.accel        = config.get('accel', 'kvm')

        self.net_id             = config.get('net_id', 0)
        self.upstream_interface = config.get('upstream_interface', 'eth0')
        self.tap_interface      = config.get('tap_interface', 'uc0')
        self.network            = config.get('network')

    def get_qemu_args(self):
        command = (
            "-uuid {uuid} -name {name} -machine pc,accel={accel}"
            " -drive file={image},format={image_format},if=virtio"
            " -device virtio-rng-pci"
            " -m {memory} -smp cores={cores},threads={threads}"
            " -netdev tap,id=vmnet{net_id},ifname={tap},script=no,downscript=no"
            " -device virtio-net-pci,netdev=vmnet{net_id},mac={mac}"
        ).format(
            uuid=self.uuid, name=self.name, accel=self.accel,
            image=self.image, image_format=self.image_format,
            memory=self.memory, cores=self.cores, threads=self.threads,
            net_id=self.net_id, tap=self.tap_interface, mac=self.mac
        )

        return command.split(" ")

    def start(self):
        # Check that VM image is available.
        if not os.path.isfile(self.image):
            logger.error("Image {} does not exist. Aborting.".format(self.image))

        # Create Bridge, VXLAN and tap interface for VM.
        create_vxlan_br_tap(
                self.net_id, self.upstream_interface, self.tap_interface, self.network
                )

        # Generate config for and run QEMU.
        qemu_args = self.get_qemu_args()
        logger.debug("QEMU args for VM {}: {}".format(self.uuid, qemu_args))
        self.vmm.start(
                uuid=self.uuid,
                migration=False,
                *qemu_args
                )

    def stop(self):
        self.vmm.stop(self.uuid)

    def get_status(self):
        return self.vmm.get_status(self.uuid)

    def get_vnc_addr(self):
        return self.vmm.get_vnc(self.uuid)

    def get_uuid(self):
        return self.uuid

    def get_name(self):
        success, json = self.vmm.execute_command(self.uuid, 'query-name')
        if success:
            return json['return']['name']

        return None
