# coding:utf-8

'''
Created on Nov 18, 2014

@author: raul
'''
from PyQt4.QtCore import QString


class Disk(object):
    def __init__(self):
        self.href = ''
        self.id = ''
        self.actions = []
        self.name = ''
        self.links = {}  # key is rel and value is href
        self.vm_href = ''
        self.vm_id = ''
        self.alias = ''
        self.image_id = ''
        self.storage_domains = set()  # this is a set 
        self.size = '' #B
        self.provisioned_size = ''
        self.actual_size = ''
        self.status_state = ''
        self.interface = ''  # the type of disk
        self.formate = ''
        self.sparse = ''
        self.bootable = ''
        self.shareable = ''
        self.wipe_after_delete = ''
        self.propagate_errors = ''
        self.activity = ''
        self.read_only = ''
        
    def __str__(self):
        val = 'href=' + self.href + ' ' \
            + 'id=' + self.id + ' ' \
            + 'name=' + self.name + ' ' \
            + 'vm_href=' + self.vm_href + ' ' \
            + 'vm_id=' + self.vm_id + ' ' \
            + 'alias=' + self.alias + ' ' \
            + 'image_id=' + self.image_id + ' ' \
            + 'size=' + self.size + ' ' \
            + 'provisioned_size=' + self.provisioned_size + ' ' \
            + 'actual_size=' + self.actual_size + ' ' \
            + 'status_state=' + self.status_state + ' ' \
            + 'interface=' + self.interface + ' ' \
            + 'formate=' + self.formate + ' ' \
            + 'sparse=' + self.sparse + ' ' \
            + 'bootable=' + self.bootable + ' ' \
            + 'shareable=' + self.shareable + ' ' \
            + 'wipe_after_delete=' + self.wipe_after_delete + ' ' \
            + 'propagate_errors=' + self.propagate_errors + ' ' \
            + 'activity=' + self.activity + ' ' \
            + 'read_only=' + self.read_only 
        return str(val)

def make_mac():  
    import uuid, random
    local_mac = uuid.uuid1().hex[-12:]
    mac = [random.randint(0x00, 0xff), random.randint(0x00, 0xff) ]  
    s = [local_mac[0:2], local_mac[2:4],local_mac[4:6],local_mac[6:8]]  
    for item in mac:  
        s.append(str("%02x" % item))  
    return ( ':'.join(s) )
    
class VM(object):
    '''
    This class is used by vm and template
    '''
    def __init__(self):
        self.vmflag = True  # True means a vm, False means a template. This is should be carefully used.
        self.href = ''
        self.id = ''
        self.actions = {}  # key is rel and value is href
        self.name = ''
        self.description = ''
        self.links = {}
        self.type = ''
        self.status_state = ''
        self.memory = ''  # KB
        self.cpu_topology_sockets = ''
        self.cpu_topology_cores = ''
        self.cpu_architecture = ''
        self.cpu_shares = ''
        self.os_type = ''
        self.os_boot_dev = ''
        self.high_availability_enabled = ''
        self.high_availability_priority = ''
        self.display_type = ''
        self.display_monitors = ''
        self.display_single_qxl_pci = ''
        self.display_allow_override = ''
        self.display_smartcard_enabled = ''
        self.display_address = ''
        self.display_port = ''
        self.display_secure_port = ''
        self.cluster_href = ''
        self.cluster_id = ''
        self.template_href = ''
        self.template_id = ''
        self.start_time = ''
        self.stop_time = ''
        self.creation_time = ''
        self.origin = ''
        self.stateless = ''
        self.delete_protected = ''
        self.sso_methods = set()  # this is a set contains the method ids.
        self.placement_policy_host_href = ''
        self.placement_policy_host_id = ''
        self.placement_policy_affinity = ''
        self.memory_policy_guaranteed = ''
        self.guest_info_ips = set()  # vm ip address
        self.usb_enabled = ''
        self.migration_downtime = ''
        self.ismonitor = ''
        self.offlinedesktopavailable = ''
        
        self.vmpool_id = ''
        self.inpool = False
        self.domain_name = ''
        self.permission_id = ''
        
        self.disks = {}
        self.xml = ''
        self.useType = ""
        
        self.vm_storage_type = ''

        #add by p_bc for cache -top
        self.vm_cache = ''
        #add by p_bc for cache -end
    
    def insertDisk(self, disk):
        self.disks[disk.id] = disk
    
    def clearDisk(self):
        self.disks.clear()
    
    def isFileSystemStorage(self):
        from common import commondata
        return str(self.vm_storage_type) == commondata.FILE_SYSTEM_STORAGE
    
    def isBlockStorage(self):
        from common import commondata
        return str(self.vm_storage_type) == commondata.BLOCK_STORAGE
    
    def __str__(self):
        return str('id=' + self.id + ' ' \
        + 'name=' + self.name + ' ' \
        + 'template_id=' + self.template_id + ' ' \
        + 'stateless=' + self.stateless + ' ' \
        + 'vmpool_id=' + self.vmpool_id + ' ' \
        + 'offlinedesktopavailable=' + self.offlinedesktopavailable + ' ')
    
class VmDict(dict):
    '''
    classdocs
    '''
    import threading
    
    _instance = None
    vmDictMutex = threading.RLock()
    
    def __init__(self):
        dict.__init__(self)
    
    def reload(self):
        self.clear()
        self.refresh()
    
    def refresh(self):
        from common.NetUtil import NetUtil
        net = NetUtil()
        VmDict.vmDictMutex.acquire()
        net.queryAllVms()
        VmDict.vmDictMutex.release()
    
    def clear(self):
        VmDict.vmDictMutex.acquire()
        dict.clear(self)
        VmDict.vmDictMutex.release()
    
    def insertVm(self, uuid, vm):
        self[uuid] = vm
        
    def getAllVms(self):
        VmDict.vmDictMutex.acquire()
        vms = self.values()
        VmDict.vmDictMutex.release()
        return vms
    
    def getVmSupportOffline(self):
        '''
        Get vm which support both online and offline.
        '''
        lst = []
        for vm in self.values():
            if vm.offlinedesktopavailable == 'true':
                lst.append(vm)
        return lst
    
    def getVmOnlineOnly(self):
        '''
        Get vm which support online only.
        '''
        lst = []
        vms = self.getAllVms()
        for vm in vms:
            if vm.offlinedesktopavailable == 'false':
                lst.append(vm)
        return lst
    
    def isVmSupportOffline(self, uuid):
        '''
        @uuid: QString
        '''
        uuid = QString(uuid)
        vm = self.getVm(uuid)
        if vm:
            return vm.offlinedesktopavailable == 'true'
        else:
            return False
        
    def isStatelessVm(self, uuid):
        '''
        @uuid: QString
        '''
        uuid = QString(uuid)
        vm = self.getVm(uuid)
        return vm.stateless == 'true'
    
    def isVmActive(self, uuid):
        uuid = QString(uuid)
        vm = self.getVm(uuid)
        return vm.status_state == 'up'
    
    def getVm(self, uuid):
        '''
        @uuid: QString
        '''
        uuid = QString(uuid)
        VmDict.vmDictMutex.acquire()
        if not self.has_key(uuid):
            from common.NetUtil import NetUtil
            net = NetUtil()
            net.queryVm(uuid)
        vm = self.get(uuid)
        VmDict.vmDictMutex.release()
        return vm
    
    def getTemplate(self, uuid):
        '''
        @uuid: QString
        '''
        uuid = QString(uuid)
        VmDict.vmDictMutex.acquire()
        if not self.has_key(uuid):
            from common.NetUtil import NetUtil
            net = NetUtil()
            net.queryVm(uuid, vmFlag=False)
        template = self.get(uuid)
        VmDict.vmDictMutex.release()
        return template
    
    def getVmDisks(self, uuid):
        '''
        @uuid: QString
        '''
        
        uuid = QString(uuid)
        vm = self.getVm(uuid)
        disks = []
        VmDict.vmDictMutex.acquire()
        print (vm)
        if not vm.disks:
            from common.NetUtil import NetUtil
            net = NetUtil()
            net.queryDisk(uuid)
        if vm.disks:
            disks = vm.disks.values()
        VmDict.vmDictMutex.release()
        return disks
    
    def getTemplateDisks(self, uuid):
        '''
        @uuid: QString
        '''
        uuid = QString(uuid)
        template = self.getTemplate(uuid)
        VmDict.vmDictMutex.acquire()
        disks = []
        if not template.disks:
            from common.NetUtil import NetUtil
            net = NetUtil()
            net.queryDisk(uuid, vmFlag=False)
        if template.disks:
            disks = template.disks.values()
        VmDict.vmDictMutex.release()
        return disks
        
    def getVmXml(self, uuid):
        '''
        @uuid: QString
        '''
        uuid = QString(uuid)
        vm = self.getVm(uuid)
        if not vm.xml:
            from offline.net.OfflineNetUtil import OfflineNetUtil
            net = OfflineNetUtil()
            net.queryVmXml(uuid)
        xml = str(vm.xml)
        return xml
        
    @staticmethod 
    def instance():
        if (VmDict._instance == None):
            VmDict._instance = VmDict()
            
        return VmDict._instance
        


