import libvirt
import os
import string
import uuid
import xml.etree.ElementTree as ET

from cephlvc.network import ArpScraper

class Domain(object):
    def __init__(self, virDomain):
        self.domain = virDomain

    def __getattr__(self, attr_name):
        if hasattr(self.domain, attr_name):
            return getattr(self.domain, attr_name)

    def disk_count(self, bus=None):
        targets = self.etree.findall('*/disk/target')

        if not bus:
            return len(targets)

        count = 0
        for target in targets:
            if target.attrib['bus'] == bus:
                count += 1
        return count

    @property
    def etree(self):
        return ET.fromstring(self.domain.XMLDesc())

    @property
    def volume_paths(self):
        paths = []
        etree = self.etree
        for source in etree.findall('*/disk/source'):
            paths.append(source.attrib['file'])
        return paths

class Cluster(object):
    def __init__(self, name, template_domain_name, virtcon):
        self.name = name
        self.template_domain_name = template_domain_name
        self.virtcon = virtcon

    def add_domain(self, data_volume_count=0, data_volume_size=0):
        new_name = self.next_domain_name()
        etree = self.template_domain.etree

        source_volume_element = etree.find('*/disk/source')
        source_volume_path = source_volume_element.attrib['file']
        source_volume = self.virtcon.storageVolLookupByPath(source_volume_path)
        volume = self.duplicate_volume(source_volume, "%s.img" % new_name)

        domain = self.create_domain(new_name, self.template_domain.etree, volume)

        disk_offset = domain.disk_count('virtio')
        for x in range(0, data_volume_count):
            vol_name = "%s-data-%02d.img" % (new_name, x)
            dev_id = "vd%s" % string.ascii_lowercase[x + disk_offset]
            volume = self.create_volume(vol_name, data_volume_size)
            self.add_volume_to_domain(domain, volume, dev_id)

        return domain

    def add_volume_to_domain(self, domain, volume, dev_id):
        xml = """
        <disk type='file' device='disk'>
          <driver name='qemu' type='qcow2'/>
          <source file='%s'/>
          <target dev='%s' bus='virtio'/>
        </disk>""" % (volume.path(), dev_id)

        domain.attachDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CONFIG)

    def create_domain(self, name, template_etree, source_volume):
        etree = template_etree

        etree.find("uuid").text = str(uuid.uuid4())
        etree.find("name").text = name

        source_volume_element = etree.find('*/disk/source')
        source_volume_element.attrib['file'] = source_volume.path()

        for mac in etree.findall('*/interface/mac'):
            mac.attrib['address'] = self.next_mac_address()