# -*- coding: utf-8 -*-
#
# This file is part of Karesansui.
#
# Copyright (C) 2009 HDE, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#

import re
import os

import web

import karesansui
from karesansui.lib.rest import Rest, auth

from karesansui.lib.virt.virt import KaresansuiVirtException, \
     KaresansuiVirtConnection
from karesansui.lib.merge import MergeGuest
from karesansui.lib.utils import get_ifconfig_info, generate_mac_address, is_param

from karesansui.gadget.guestby1disk import create_disk_job, validates_disk
from karesansui.gadget.guestby1nic import create_nic_job, validates_nic

from karesansui.db.access.machine import findbyguest1
from karesansui.db.access._2pysilhouette import save_job_collaboration
from karesansui.db.access.machine2jobgroup import new as m2j_new
from karesansui.db.model._2pysilhouette import JobGroup, Job

from karesansui.lib.checker import Checker, \
     CHECK_EMPTY, CHECK_VALID, CHECK_LENGTH, \
     CHECK_STARTROOT, CHECK_EXIST, CHECK_ISDIR

class GuestBy1Device(Rest):

    @auth
    def _GET(self, *param, **params):
        (host_id, guest_id) = self.chk_guestby1(param)
        if guest_id is None: web.notfound()
        
        model = findbyguest1(self.orm, guest_id)

        # virt
        self.kvc = KaresansuiVirtConnection()
        try:
            domname = self.kvc.uuid_to_domname(model.uniq_key)
            if not domname: return web.conflict(web.ctx.path)
            
            virt = self.kvc.search_kvg_guests(domname)[0]
            
            guest = MergeGuest(model, virt)

            phydev = []
            phydev_regex = re.compile(r"xenbr")
            
            for dev,dev_info in get_ifconfig_info().iteritems():
                try:
                    if phydev_regex.match(dev):
                        phydev.append(dev)
                except:
                    pass
                    
            phydev.sort()
            self.view.phydev = phydev # Physical device
            self.view.disk_info = virt.get_disk_info() # Disk info
            self.view.virnet = sorted(self.kvc.list_active_network()) # Virtual device
            self.view.mac_address = generate_mac_address() # new mac address
            self.view.ifinfo = virt.get_interface_info() # interface info
            self.view.guest = guest # virt obj off
            
        finally:
            self.kvc.close()

        return True

    @auth
    def _POST(self, *param, **params):
        (host_id, guest_id) = self.chk_guestby1(param)
        if guest_id is None: web.notfound()

        model = findbyguest1(self.orm, guest_id)

        # virt
        kvc = KaresansuiVirtConnection()
        try:
            domname = kvc.uuid_to_domname(model.uniq_key)
            if not domname: return web.conflict(web.ctx.path)
            virt = kvc.search_kvg_guests(domname)[0]
            nic_info = virt.get_interface_info()
        finally:
            kvc.close()

        # -- Nic
        if self.input.device_type == "nic":
            if not validates_nic(self):
                return web.badrequest(self.view.alert)

            f_chk = True
            for x in nic_info:
                if x['mac']['address'] == self.input.mac_address:
                    f_chk = False
                    break
            if f_chk is False:
                return web.badrequest(_('Specified MAC address is already defined.'))
            
            mac = self.input.mac_address
            bridge = None
            network = None
            if self.input.nic_type == "phydev":
                bridge = self.input.phydev
            elif self.input.nic_type == "virnet":
                network = self.input.virnet
                
            self.logger.debug('spinning off create_nic_job dom=%s, mac=%s, bridge=%s, network=%s' % (domname, mac, bridge, network))
            create_nic_job(self,model,domname,mac,bridge,network)
            return web.accepted()

        # -- Disk
        elif self.input.device_type == "disk":
            if not validates_disk(self):
                return web.badrequest(self.view.alert)
            
            if is_param(self.input, "sparse"):
                sparse = self.input.sparse
            else:
                sparse = None

            disk_size = self.input.disk_size

            if create_disk_job(self, model, domname, sparse, disk_size) is True:
                return web.accepted()
            else:
                return False

        else: # Not Found
            return False

urls = (
    '/host/(\d+)/guest/(\d+)/device/?(\.part|\.html)?$', GuestBy1Device,
    )
