from JumpScale import j
import JumpScale.grid.agentcontroller
import JumpScale.lib.lxc
import JumpScale.baselib.serializers

class jumpscale_netmgr(j.code.classGetBase()):
    """
    net manager

    """
    def __init__(self):

        self._te = {}
        self.actorname = "netmgr"
        self.appname = "jumpscale"
        #jumpscale_netmgr_osis.__init__(self)
        self.client = j.core.osis.getClientByInstance('main')
        self.osisvfw = j.core.osis.getClientForCategory(self.client, 'vfw', 'virtualfirewall')
        self.nodeclient = j.core.osis.getClientForCategory(self.client, 'system', 'node')
        self.agentcontroller = j.clients.agentcontroller.get()
        self.json = j.db.serializers.getSerializerType('j')

    def fw_check(self, fwid, gid, **kwargs):
        """
        will do some checks on firewall to see is running, is reachable over ssh, is connected to right interfaces
        param:fwid firewall id
        param:gid grid id
        """
        fwobj = self.osisvfw.get(fwid)
        args = {'name': '%s_%s' % (fwobj.domain, fwobj.name)}
        return self.agentcontroller.executeJumpscript('jumpscale', 'vfs_checkstatus', nid=fwobj.nid, gid=fwobj.gid, args=args)['result']

    def fw_create(self, gid, domain, login, password, publicip, type, networkid, publicgwip, publiccidr, **kwargs):
        """
        param:domain needs to be unique name of a domain,e.g. a group, space, ... (just to find the FW back)
        param:gid grid id
        param:nid node id
        param:masquerade do you want to allow masquerading?
        param:login admin login to the firewall
        param:password admin password to the firewall
        param:host management address to manage the firewall
        param:type type of firewall e.g routeros, ...
        """
        fwobj = self.osisvfw.new()
        fwobj.domain = domain
        fwobj.id = networkid
        fwobj.gid = gid
        fwobj.pubips.append(publicip)
        fwobj.type =  type
        key = self.osisvfw.set(fwobj)[0]
        args = {'name': '%s_%s' % (fwobj.domain, fwobj.name)}
        if type == 'routeros':
            args = {'networkid': networkid,
                    'password': password,
                    'publicip': publicip,
                    'publicgwip': publicgwip,
                    'publiccidr': publiccidr,
                    }
            result = self.agentcontroller.executeJumpscript('jumpscale', 'vfs_create_routeros', role='fw', gid=gid, args=args, queue='hypervisor')
            if result['state'] != 'OK':
                self.osisvfw.delete(key)
                raise RuntimeError("Failed to create create fw for domain %s job was %s" % (domain, result['id']))
            data = result['result']
            fwobj.host = data['internalip']
            fwobj.username = data['username']
            fwobj.password = data['password']
            fwobj.nid = data['nid']
            self.osisvfw.set(fwobj)
        else:
            return self.agentcontroller.executeJumpscript('jumpscale', 'vfs_create', role='fw', gid=gid, args=args)['result']

    def fw_move(self, fwid, targetNid, **kwargs):
        fwobj = self.osisvfw.get(fwid)
        srcnode = self.nodeclient.get("%s_%s" % (fwobj.gid, fwobj.nid))
        trgnode = self.nodeclient.get("%s_%s" % (fwobj.gid, targetNid))
        def get_backplane_ip(node):
            for mac, nicinfo in node.netaddr.iteritems():
                if nicinfo[0] == 'backplane1':
                    return nicinfo[1]
        srcip = get_backplane_ip(srcnode)
        trgip = get_backplane_ip(trgnode)
        sshkey = None
        sshpath = j.system.fs.joinPaths(j.dirs.cfgDir, 'sshkey')
        if j.system.fs.exists(sshpath):
            sshkey = j.system.fs.fileGetContents(sshpath)
        args = {'networkid': fwobj.id,
                'sourceip': srcip,
                'targetip': trgip,
                'sshkey': sshkey}
        job = self.agentcontroller.executeJumpscript('jumpscale', 'vfs_migrate_routeros', nid=targetNid, gid=fwobj.gid, args=args)
        if job['state'] != 'OK':
            raise RuntimeError("Failed to move routeros check job %(guid)s" % job)
        fwobj.nid = targetNid
        self.osisvfw.set(fwobj)
        return True

    def fw_get_ipaddress(self, fwid, macaddress):
        fwobj = self.osisvfw.get(fwid)
        args = {'fwobject': fwobj.obj2dict(), 'macaddress': macaddress}
        job = self.agentcontroller.executeJumpscript('jumpscale', 'vfs_get_ipaddress_routeros', gid=fwobj.gid, nid=fwobj.nid, args=args)
        if job['state'] != 'OK':
            raise RuntimeError("Failed to retreive IPAddress for macaddress %s. Error: %s" % (macaddress, job['result']['errormessage']))
        return job['result']

    def fw_set_password(self, fwid, username, password):
        fwobj = self.osisvfw.get(fwid)
        args = {'fwobject': fwobj.obj2dict(), 'username': username, 'password': password}
        job = self.agentcontroller.executeJumpscript('jumpscale', 'vfs_set_password_routeros', gid=fwobj.gid, nid=fwobj.nid, args=args)
        if job['state'] != 'OK':
            raise RuntimeError("Failed to set password. Error: %s" % (job['result']['errormessage']))
        return job['result']

    def fw_delete(self, fwid, gid, **kwargs):
        """
        param:fwid firewall id
        param:gid grid id
        """
        fwobj = self.osisvfw.get(fwid)
        args = {'name': '%s_%s' % (fwobj.domain, fwobj.name)}
        if fwobj.type == 'routeros':
            args = {'networkid': fwobj.id}
            if fwobj.nid:
                job = self.agentcontroller.executeJumpscript('jumpscale', 'vfs_destroy_routeros', nid=fwobj.nid, gid=fwobj.gid, args=args)
                if job['state'] != 'OK':
                    raise RuntimeError("Failed to remove vfw with id %s" % fwid)
            self.osisvfw.delete(fwid)
        else:
            result = self.agentcontroller.executeJumpscript('jumpscale', 'vfs_delete', nid=fwobj.nid, gid=fwobj.gid, args=args)['result']
            if result: