from mykvm import BASE_IMAGES_PATH
from mykvm import IMAGES_PATH
from mykvm import MYKVM_CONFIG_PATH

from mykvm.util import bcolors

import subprocess

class QemuImgCommand(object):

    def __init__(self, vm):
        self.vm = vm

    def create(self):
        cmd = []
        cmd.append("qemu-img")
        cmd.append("create")
        cmd.append("-b")
        cmd.append(BASE_IMAGES_PATH + '/' + self.vm.get_template())
        cmd.append("-f")
        cmd.append("qcow2")
        cmd.append(IMAGES_PATH + '/' + self.vm.get_name() + ".qcow2")

        #print " ".join(cmd)
        subprocess.call(cmd)

    def destroy(self):
        cmd = []
        cmd.append("sudo")
        cmd.append("rm")
        cmd.append("-f")
        cmd.append(IMAGES_PATH + '/' + self.vm.get_name() + ".qcow2")

        subprocess.call(cmd)

class VirtInstallCommand(object):

    def __init__(self, vm):
        self.vm = vm

    def execute(self):
        cmd = []
        cmd.append("sudo")
        cmd.append("virt-install")
        cmd.append("--virt-type")
        cmd.append("kvm") 
        # cmd.append("qemu") # virtualbox vm
        cmd.append("--name") 
        cmd.append(self.vm.get_name())
        # nested kvm : 
        # modprobe -r kvm-intel && modprobe kvm-intel nested=1 && cat /sys/module/kvm_intel/parameters/nested
        # --cpu=host
        if self.vm.is_kvm_nested():
            cmd.append("--cpu")
            cmd.append("core2duo,+vmx") 
        cmd.append("--vcpus")
        cmd.append(self.vm.get_vcpus())
        cmd.append("--ram")
        cmd.append(self.vm.get_ram())
        cmd.append("--disk")
        cmd.append(IMAGES_PATH + '/' + self.vm.get_name() + ".qcow2,format=qcow2")
        for netdev in self.vm.get_netdevs():
            cmd.append("--network")
            cmd.append("network=" + netdev.get_network())
            if netdev.get_mac():
                cmd.append("--mac")
                cmd.append(netdev.get_mac()) 
        cmd.append("--graphics")
        cmd.append("vnc,listen=0.0.0.0")
        cmd.append("--noautoconsole")
        cmd.append("--os-type=linux")
        cmd.append("--os-variant=ubuntuprecise")
        cmd.append("--boot")
        cmd.append("hd")

        #print " ".join(cmd)
        subprocess.call(cmd)

class VirshCommand(object):

    def __init__(self, vm):
        self.vm = vm

    def start(self):
        cmd = []

        cmd.append("sudo")
        cmd.append("virsh")
        cmd.append("start")
        cmd.append(self.vm.get_name())

        subprocess.call(cmd)
        
    def shutdown(self):
        cmd = []

        cmd.append("sudo")
        cmd.append("virsh")
        cmd.append("shutdown")
        cmd.append(self.vm.get_name())

        subprocess.call(cmd)

    def destroy(self):
        cmd = []

        cmd.append("sudo")
        cmd.append("virsh")
        cmd.append("destroy")
        cmd.append(self.vm.get_name())

        subprocess.call(cmd)
    
    def undefine(self):
        cmd = []

        cmd.append("sudo")
        cmd.append("virsh")
        cmd.append("undefine")
        cmd.append(self.vm.get_name())

        subprocess.call(cmd)

class VirshStatusCommand(object):

    def list(self):
        cmd = []

        cmd.append("sudo")
        cmd.append("virsh")
        cmd.append("list")
        cmd.append("--all")

        subprocess.call(cmd)

class VirshNetCommand(object):

    def __init__(self, network, idx):
        self.network = network
        self.idx = idx
        self.net_conf_file = MYKVM_CONFIG_PATH + '/' + 'net_' + network.get_name() + '.xml'

    def modify_resolv_conf(self):
        resolv_conf_head = """
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN

nameserver %s
nameserver 8.8.8.8        
"""
        head_file = MYKVM_CONFIG_PATH + '/' + 'head'
        with open(head_file, 'w') as f:
            print >> f, resolv_conf_head % (self.network.get_ip())  
            
        cmd = []
        cmd.append("sudo")
        cmd.append("cp")
        cmd.append(head_file)
        cmd.append("/etc/resolvconf/resolv.conf.d")

        subprocess.call(cmd)    
        
        cmd = []
        cmd.append("sudo")
        cmd.append("/sbin/resolvconf")
        cmd.append("-u")

        subprocess.call(cmd)                   

    def generate_net_config(self):                        
        forward = ""
        if self.network.is_external():
            forward = "\n  <forward mode='nat'/>"
            
        subnet = '.'.join(self.network.get_ip().split('.')[0:3])
        
        hosts = []
        for netdev in self.network.get_netdevs():
            name = netdev.get_vm().get_name()
            ip = netdev.get_ip()
            mac = "52:54:00:00:%02X:%02X" % (self.idx, int(ip.split('.')[-1]))
            netdev.set_mac(mac)
            hosts.append("      <host mac='%s' name='%s' ip='%s' />" % (mac, name, ip))

        host_info = "\n".join(hosts)
        
        net_config_template = """
<network>
  <name>%s</name>%s
  <bridge name='virbr%s'/>
  <mac address='52:54:00:4A:0F:%02X'/>
  <ip address='%s' netmask='255.255.255.0'>
    <dhcp>
      <range start='%s.2' end='%s.253' />
%s      
    </dhcp>
  </ip>
</network>
    """
        
        net_conf = net_config_template % (self.network.get_name(),
                                          forward,
                                          self.network.get_name(),
                                          self.idx,
                                          self.network.get_ip(),
                                          subnet,
                                          subnet,
                                          host_info)

        with open(self.net_conf_file, 'w') as f:
            print >> f, net_conf

    def restart(self):
        print bcolors.OKGREEN + '* restart network - ' + self.network.get_name() + bcolors.ENDC
        
        cmd = []

        cmd.append("sudo")
        cmd.append("virsh")
        cmd.append("net-destroy")
        cmd.append(self.network.get_name())

        subprocess.call(cmd)
        
        cmd = []
        cmd.append("sudo")
        cmd.append("virsh")
        cmd.append("net-undefine")
        cmd.append(self.network.get_name())

        subprocess.call(cmd)

        self.generate_net_config()

        cmd = []
        cmd.append("sudo")
        cmd.append("virsh")
        cmd.append("net-define")
        cmd.append("--file")
        cmd.append(self.net_conf_file)

        subprocess.call(cmd)

        cmd = []
        cmd.append("sudo")
        cmd.append("virsh")
        cmd.append("net-start")
        cmd.append(self.network.get_name())

        subprocess.call(cmd)
        
        cmd = []
        cmd.append("sudo")
        cmd.append("virsh")
        cmd.append("net-autostart")
        cmd.append(self.network.get_name())

        if self.network.is_autostart():
            subprocess.call(cmd)
            
        if self.idx == 1:
            print bcolors.OKGREEN + '* add new nameserver - ' + self.network.get_ip() + bcolors.ENDC + '\n'
            self.modify_resolv_conf()
            
