# -*- coding: utf-8 -*-


from genshi.template import TemplateLoader
from xml.dom.minidom import parseString
from subprocess import check_call ,CalledProcessError
from pkg_resources import resource_filename
import os
import re
import libvirt

class DomInfo:

  def __init__(self, name, id, hostid=0, vcpu=1, mem=0.25, con=None, mac=None, virtio=None, isoimg=None, drivertype=None, hddsize=None, arptbl = None, lun = None):
    if con == None:
      self.name = name
      self.vcpu = vcpu
      self.id = id
      self.mem = mem
      self.maxmem = mem
      self.virtio = virtio
      self.isoimg = isoimg
      self.drivertype = drivertype
      self.hddsize = hddsize
      self.lun = lun
      self.mac = mac
      self.hostid = hostid

    else:
      dom = None
      if id!=None:
        dom = con.lookupByID(id)
      else:
        dom = con.lookupByName(name)
      self.domxml = parseString(dom.XMLDesc(False))
      self.name = dom.name()
      info = dom.info()
      self.status = u"実行中" if info[0] == 1 else u"停止中"
      self.vcpu = info[3]
      self.mem = float(info[1])/(1024*1024)
      self.vncport = self.getVncPort()
      self.mac = self.getMacAddress()
      self.virtio = self.getVirtio()
      self.isoimg = self.getIsoImg()
      self.disktype = self.getDiskType()
      self.lun = 0
      m = self.mac.split(':')
      if m != None:
        self.id = int(m[len(m)-1],16)
      if arptbl != None and mac !='-':
        self.ip = arptable[mac]
      else:
        self.ip = '-'
#      self.domxml.unlink()
        
  def getMacAddress(self):
    for mac in self.domxml.getElementsByTagName("mac"):
      return mac.getAttribute('address')
    return '-'

  def getVirtio(self):
    for target in self.domxml.getElementsByTagName("target"):
      if target.getAttribute('bus') == 'virtio':
        return True
    return False

  def getVncPort(self):
    for graphic in self.domxml.getElementsByTagName("graphics"):
      if graphic.getAttribute('type')==u'vnc':
        return graphic.getAttribute('port')
    return '-'

  def getIsoImg(self):
    for disk in self.domxml.getElementsByTagName('disk'):
      device = disk.getAttribute('device')
      if device == 'cdrom':
        for source in disk.getElementsByTagName('source'):
          file = source.getAttribute('file')
          if file!='':
            return file.rsprit('/',1)[1]
    return None

  def getDiskType(self):
    for disk in self.domxml.getElementsByTagName('disk'):
      for driver in disk.getElementsByTagName('driver'):
          drivertype = driver.getAttribute('type')
          if file!='':
            return drivertype
    return 'raw'

  def toJSON(self):
    return {'name': self.name, 
            'vcpu': self.vcpu, 
            'mem': self.mem, 
            'vncport': self.vncport, 
            'mac': self.mac, 
            'ip': self.ip,
            'virtio': virtio,
            'isoimg': self,
            'id': self.id}            

#    // macaddress
#    // ip
#    // virtio
#    // cdrom
#    // mem
#    // vcpu
#    // name
#    // status
#    // hostid
  
  def createXML(self, hostcnf,storagecnf):
    loader = TemplateLoader(resource_filename('ienocloud', 'templates'), auto_reload=False)
    tmpl = loader.load('define.xml')
    xml =tmpl.generate(dom=self,host=hostcnf,storage=storagecnf).render('xml')
    return xml

  def create(self, url ,hostcnf ,storagecnf):
    imgfile = hostcnf['imagedir']+'/'+self.name+'.'+self.drivertype
    m = None

    try:
      m = re.match('.+//(.+@|)(.+)/' ,url)
      if m:
        check_call(["ssh" ,"root@" + hostcnf['address'] ,"ls" ,imgfile])
      else:
        check_call(["ls" ,imgfile])

    except CalledProcessError:
      print("image cloud not found.")
      if m:
        check_call(["ssh" ,"root@" + hostcnf['address'] ,"qemu-img", "create","-f", self.drivertype, imgfile, str(self.hddsize)+"G"])
      else:
        check_call(["qemu-img", "create","-f", self.drivertype, imgfile, str(self.hddsize)+"G"])

    con = libvirt.open(url)
    self.id = getAvailableVMID(con)
    xml = self.createXML(hostcnf ,storagecnf)
    con.defineXML(xml)
    dom = con.lookupByName(self.name)
    dom.create()


def getDomain(con, hostcnf, vmname):
  try:
    return con.lookupByName(vmname)
  except libvirt.libvirtError:
    return None    
  
   
def create(con, hostcnf,storagecnf):
  imgfile = hostcnf['imagedir']+'/'+self.name+'.'+vm['drivertype']
  try:  
    check_call(["ssh" ,"root@" + hostcnf['address'] ,"ls" ,imgfile])

  except CalledProcessError:
    print("image cloud not found.")
    check_call(["ssh"  ,"root@" + hostcnf['address'] ,"qemu-img", "create","-f", self.drivertype, imgfile, str(self.hddsize)+"G"])
  
  xml = createXML(hostcnf,storagecnf)
  con.defineXML(xml)
  dom = c.lookupByName(self.name)
  dom.create()

def getIDfromDom(dom):
  domxml = parseString(dom.XMLDesc(False))  
  print(domxml)
  for mac in domxml.getElementsByTagName("mac"):
    mac = mac.getAttribute('address')
    m = mac.split(':')
    return int(m[len(m)-1],16)
  return -1

def getAvailableVMID(con):
  ## Add booting domains
  idlist = []
  vmlist = con.listDomainsID()
  for id in vmlist:
    dom = con.lookupByID(id)
    i = getIDfromDom(dom)
    if i!=-1:
      idlist.append(i)
          
  list = con.listDefinedDomains()
  for name in list:
    dom = con.lookupByName(name)
    i = getIDfromDom(dom)
    if i!=-1:
      idlist.append(i)
  idlist.sort()
  c = 1
  
  for i in range(0,len(idlist)):
    if idlist[i]!= c:
      break
    c = c + 1
  return c
  
#con = 
storage = {
'address': '192.168.1.2',
'targetname': 'xxxxxxxx',
'lun': 1
}

dom = DomInfo(name='VMName', id=1,vcpu=1,mem=0.5,virtio=False,isoimg=None, hddsize=1, lun=1, drivertype='raw')

host = {
'address':'192.168.1.2',
'imagedir': '/tmp',
'bridge':"dmzbr0",
'vnetdevice':"vnet",
#'mac': "00:03:04:%02X:%02X"
}

storage = {
'port': '3260',
'address': '192.168.2.8',
'targetname': 'iqn.iscsi',
}

# print dom.createXML(hostcnf=host, storagecnf=storage)


data  = {
'vcpu': 1,
'name': 'VMName', 
'id': 19,
'mem': 0.25,
'maxmem': 0.5,
'virtio': False,
'isoimg': "/home/homecloud/iso/maverick-server-amd64.iso",
'drivertype': 'raw',
'hddsize': 0.5
}


#con = libvirt.open("qemu+ssh://root@" + host['address'] + "/system")
#availableId = getAvailableVMID(con)
#data['id'] = availableId#create(host,data,storage)
#print createXML(host,data,storage)
#print getDomain(host,"VMname")
#create(host,data)
