# -*- 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 web
import simplejson as json

import karesansui
from karesansui.lib.rest import Rest, auth
from karesansui.lib.const import VIRT_COMMAND_DELETE_NETWORK, VIRT_COMMAND_UPDATE_NETWORK
from karesansui.db.access.machine import findbyhost1
from karesansui.db.access._2pysilhouette import jobgroup_findbyuniqkey
from karesansui.lib.virt.virt import KaresansuiVirtException, \
     KaresansuiVirtConnection
from karesansui.db.access._2pysilhouette import save_job_collaboration
from karesansui.db.access.machine2jobgroup import new as m2j_new

from pysilhouette.command import dict2command
from karesansui.db.model._2pysilhouette import Job, JobGroup
from karesansui.gadget.hostby1network import validates_network

class HostBy1NetworkBy1(Rest):
    @auth
    def _GET(self, *param, **params):
        host_id = self.chk_hostby1(param)
        if host_id is None: return web.notfound()

        network_name = param[1]
        if not (network_name and host_id):
            web.badrequest()

        kvc = KaresansuiVirtConnection()
        try:
            try:
                network = kvc.search_kvn_networks(network_name)[0] # throws KaresansuiVirtException
                info = network.get_info()
            except KaresansuiVirtException, e:
                # network not found
                self.logger.debug("Network not found. name=%s" % network_name)
                return web.notfound()
        finally:
            kvc.close()

        cidr = '%s/%s' % (info['ip']['address'], info['ip']['netmask'])
        network = dict(name=info['name'],
                       cidr=cidr,
                       dhcp_start=info['dhcp']['start'],
                       dhcp_end=info['dhcp']['end'],
                       forward_dev=info['forward']['dev'],
                       forward_mode=info['forward']['mode'],
                       bridge=info['bridge']['name'],
                       )
        self.view.info = info
        self.view.network = network
        return True

    @auth
    def _PUT(self, *param, **params):
        host_id = self.chk_hostby1(param)
        if host_id is None: return web.notfound()

        network_name = param[1]
        if not (network_name and host_id):
            return web.badrequest()

        if not validates_network(self, network_name=network_name):
            self.logger.debug("Network update failed. Did not validate.")
            return web.badrequest(self.view.alert)

        self.logger.debug("Params: %s" % self.input)
        # <Storage {'bridge': u'virbr0', 'cidr': u'192.168.123.1/255.255.255.0', 'dhcp_start': u'192.168.123.2', 'dhcp_end': u'192.168.123.252'}>
        cidr = self.input.cidr
        dhcp_start = self.input.dhcp_start
        dhcp_end = self.input.dhcp_end
        bridge = self.input.bridge
        forward_mode = getattr(self.input, 'forward_mode', '')

        #
        # spin off update job
        #
        options = {'name' : network_name,
                   'cidr': cidr,
                   'dhcp-start': dhcp_start,
                   'dhcp-end' : dhcp_end,
                   'bridge-name' : bridge,
                   'forward-mode' : forward_mode,
                  }

        self.logger.debug('spinning off network_update_job options=%s' % (options))

        host = findbyhost1(self.orm, host_id)

        _cmd = dict2command(
            "%s/%s" % (karesansui.config['application.bin.dir'], VIRT_COMMAND_UPDATE_NETWORK), options)
            
        #_jobgroup = JobGroup('Create network', karesansui.sheconf['env.uniqkey'])
        #_jobgroup.jobs.append(Job('Create network', 0, _cmd))
        
        # Job Registration
        _jobgroup = JobGroup('Update network: %s' % network_name, karesansui.sheconf['env.uniqkey'])
        _jobgroup.jobs.append(Job('Update network', 0, _cmd))
            
        _machine2jobgroup = m2j_new(machine=host,
                                    jobgroup_id=-1,
                                    uniq_key=karesansui.sheconf['env.uniqkey'],
                                    created_user=self.me,
                                    modified_user=self.me,
                                    )
            
        save_job_collaboration(self.orm,
                               self.pysilhouette.orm,
                               _machine2jobgroup,
                               _jobgroup,
                               )

        self.logger.debug('(Create network) Job group id==%s', _jobgroup.id)
        url = '%s/job/%s.part' % (web.ctx.home, _jobgroup.id)
        self.logger.debug('Returning Location: %s' % url)

        return web.accepted(url=url)

    @auth
    def _DELETE(self, *param, **params):
        host_id = self.chk_hostby1(param)
        if host_id is None: return web.notfound()
        
        network_name = param[1]
        if not (network_name and host_id):
            return web.badrequest()

        if network_name == 'default':
            return web.badrequest()

        host = findbyhost1(self.orm, host_id)

        options = {}
        options['name'] = network_name
        _cmd = dict2command(
            "%s/%s" % (karesansui.config['application.bin.dir'], VIRT_COMMAND_DELETE_NETWORK), options)
            
        # Job Registration
        _jobgroup = JobGroup('Delete network: %s' % network_name, karesansui.sheconf['env.uniqkey'])
        _jobgroup.jobs.append(Job('Delete network', 0, _cmd))
            
        _machine2jobgroup = m2j_new(machine=host,
                                    jobgroup_id=-1,
                                    uniq_key=karesansui.sheconf['env.uniqkey'],
                                    created_user=self.me,
                                    modified_user=self.me,
                                    )
            
        save_job_collaboration(self.orm,
                               self.pysilhouette.orm,
                               _machine2jobgroup,
                               _jobgroup,
                               )
        
        self.logger.debug('(Delete network) Job group id==%s', _jobgroup.id)
        url = '%s/job/%s.part' % (web.ctx.home, _jobgroup.id)
        self.logger.debug('Returning Location: %s' % url)

        return web.accepted()

urls = (
    '/host/(\d+)/network/([^\./]+)[/]?(\.html|\.part|\.json)?$', HostBy1NetworkBy1,
    )

