import commands
from planetstack.config import Config
from openstack.client import OpenStackClient

class OpenStackDriver:

    def __init__(self, config = None, client=None): 
        if config:
            self.config = Config(config)
        else:
            self.config = Config() 

        self.admin_client = OpenStackClient()
        self.admin_user = self.admin_client.keystone.users.find(name=self.admin_client.keystone.username)

        if client:
            self.shell = client
        else:
            self.shell = OpenStackClient()

    def create_role(self, name):
        roles = self.shell.keystone.roles.findall(name=name)
        if not roles:
            role = self.shell.keystone.roles.create(name)
        else:
            role = roles[0]
        return role

    def delete_role(self, filter):
        roles = self.shell.keystone.roles.findall(**filter)
        for role in roles:
            self.shell.keystone.roles.delete(role)
        return 1

    def create_tenant(self, tenant_name, enabled, description):
        """Create keystone tenant. Suggested fields: name, description, enabled"""  
        tenants = self.shell.keystone.tenants.findall(name=tenant_name)
        if not tenants:
            fields = {'tenant_name': tenant_name, 'enabled': enabled, 
                      'description': description}  
            tenant = self.shell.keystone.tenants.create(**fields)
        else:
            tenant = tenants[0]

        # always give the admin user the admin role to any tenant created 
        # by the driver. 
        self.add_user_role(self.admin_user.id, tenant.id, 'admin')
        return tenant

    def update_tenant(self, id, **kwds):
        return self.shell.keystone.tenants.update(id, **kwds)

    def delete_tenant(self, id):
        ctx = self.shell.nova_db.ctx
        tenants = self.shell.keystone.tenants.findall(id=id)
        for tenant in tenants:
            # nova does not automatically delete the tenant's instances
            # so we manually delete instances before deleteing the tenant   
            instances = self.shell.nova_db.instance_get_all_by_filters(ctx,
                       {'project_id': tenant.id}, 'id', 'asc')
            client = OpenStackClient(tenant=tenant.name)
            driver = OpenStackDriver(client=client)
            for instance in instances:
                driver.destroy_instance(instance.id)
            self.shell.keystone.tenants.delete(tenant)
        return 1

    def create_user(self, name, email, password, enabled):
        users = self.shell.keystone.users.findall(email=email)
        if not users:
            fields = {'name': name, 'email': email, 'password': password,
                      'enabled': enabled}
            user = self.shell.keystone.users.create(**fields)
        else: 
            user = users[0]
        return user

    def delete_user(self, id):
        users = self.shell.keystone.users.findall(id=id)
        for user in users:
            # delete users keys
            keys = self.shell.nova.keypairs.findall()
            for key in keys:
                self.shell.nova.keypairs.delete(key)
            self.shell.keystone.users.delete(user)
        return 1 

    def add_user_role(self, kuser_id, tenant_id, role_name):
        user = self.shell.keystone.users.find(id=kuser_id)
        tenant = self.shell.keystone.tenants.find(id=tenant_id)
        role = self.shell.keystone.roles.find(name=role_name)

        role_found = False
        user_roles = user.list_roles(tenant.id)
        for user_role in user_roles:
            if user_role.name == role.name:
                role_found = True
        if not role_found:
            tenant.add_user(user, role)

        return 1

    def delete_user_role(self, kuser_id, tenant_id, role_name):
        user = self.shell.keystone.users.find(id=kuser_id)
        tenant = self.shell.keystone.tenants.find(id=tenant_id)
        role = self.shell.keystone.roles.find(name=role_name)

        role_found = False
        user_roles = user.list_roles(tenant.id)
        for user_role in user_roles:
            if user_role.name == role.name:
                role_found = True
        if role_found:
            tenant.remove_user(user, role)

        return 1 

    def update_user(self, id, fields):
        if 'password' in fields:
            self.shell.keystone.users.update_password(id, fields['password'])
        if 'enabled' in fields:
            self.shell.keystone.users.update_enabled(id, fields['enabled']) 
        return 1 

    def create_router(self, name, set_gateway=True):
        routers = self.shell.quantum.list_routers(name=name)['routers']
        if routers:
            router = routers[0]
        else:
            router = self.shell.quantum.create_router({'router': {'name': name}})['router']
        # add router to external network
        if set_gateway:
            nets = self.shell.quantum.list_networks()['networks']
            for net in nets:
                if net['router:external'] == True: 
                    self.shell.quantum.add_gateway_router(router['id'],
                                                          {'network_id': net['id']})
        
        return router

    def delete_router(self, id):
        routers = self.shell.quantum.list_routers(id=id)['routers']
        for router in routers:
            self.shell.quantum.delete_router(router['id'])
            # remove router form external network
            #nets = self.shell.quantum.list_networks()['networks']
            #for net in nets:
            #    if net['router:external'] == True:
            #        self.shell.quantum.remove_gateway_router(router['id'])

    def add_router_interface(self, router_id, subnet_id):
        router = self.shell.quantum.show_router(router_id)['router']
        subnet = self.shell.quantum.show_subnet(subnet_id)['subnet']
        if router and subnet:
            self.shell.quantum.add_interface_router(router_id, {'subnet_id': subnet_id})

    def delete_router_interface(self, router_id, subnet_id):
        router = self.shell.quantum.show_router(router_id)
        subnet = self.shell.quantum.show_subnet(subnet_id)
        if router and subnet:
            self.shell.quantum.remove_interface_router(router_id, {'subnet_id': subnet_id})
 
    def create_network(self, name, shared=False):
        nets = self.shell.quantum.list_networks(name=name)['networks']
        if nets: 
            net = nets[0]
        else:
            net = self.shell.quantum.create_network({'network': {'name': name, 'shared': shared}})['network']
        return net
 
    def delete_network(self, id):
        nets = self.shell.quantum.list_networks()['networks']
        for net in nets:
            if net['id'] == id:
                # delete_all ports
                self.delete_network_ports(net['id'])
                # delete all subnets:
                for subnet_id in net['subnets']:
                    self.delete_subnet(subnet_id)
                self.shell.quantum.delete_network(net['id'])
        return 1

    def delete_network_ports(self, network_id):
        ports = self.shell.quantum.list_ports()['ports']
        for port in ports:
            if port['network_id'] == network_id:
                self.shell.quantum.delete_port(port['id'])
        return 1         

    def delete_subnet_ports(self, subnet_id):
        ports = self.shell.quantum.list_ports()['ports']
        for port in ports:
            delete = False
            for fixed_ip in port['fixed_ips']:
                if fixed_ip['subnet_id'] == subnet_id:
                    delete=True
                    break
            if delete:
                self.shell.quantum.delete_port(port['id'])
        return 1
 
    def create_subnet(self, name, network_id, cidr_ip, ip_version, start, end):
        #nets = self.shell.quantum.list_networks(name=network_name)['networks']
        #if not nets:
        #    raise Exception, "No such network: %s" % network_name   
        #net = nets[0]

        subnet = None 
        subnets = self.shell.quantum.list_subnets()['subnets']
        for snet in subnets:
            if snet['cidr'] == cidr_ip and snet['network_id'] == network_id:
                subnet = snet

        if not subnet:
            allocation_pools = [{'start': start, 'end': end}]
            subnet = {'subnet': {'name': name,
                                 'network_id': network_id,
                                 'ip_version': ip_version,
                                 'cidr': cidr_ip,
                                 'dns_nameservers': ['8.8.8.8', '8.8.4.4'],
                                 'allocation_pools': allocation_pools}}
            subnet = self.shell.quantum.create_subnet(subnet)['subnet']
            self.add_external_route(subnet)
        # TODO: Add route to external network
        # e.g. #  route add -net 10.0.3.0/24 dev br-ex gw 10.100.0.5 
        return subnet

    def update_subnet(self, id, fields):
        return self.shell.quantum.update_subnet(id, fields)

    def delete_subnet(self, id):
        #return self.shell.quantum.delete_subnet(id=id)
        # inefficient but fault tolerant
        subnets = self.shell.quantum.list_subnets()['subnets']
        for subnet in subnets:
            if subnet['id'] == id:
                self.delete_subnet_ports(subnet['id'])
                self.shell.quantum.delete_subnet(id)
                self.delete_external_route(subnet)
        return 1

    def get_external_routes(self):
        status, output = commands.getstatusoutput('route')
        routes = output.split('\n')[3:]
        return routes

    def add_external_route(self, subnet, routes=[]):
        if not routes:
            routes = self.get_external_routes()
 
        ports = self.shell.quantum.list_ports()['ports']

        gw_ip = subnet['gateway_ip']
        subnet_id = subnet['id']

        # 1. Find the port associated with the subnet's gateway
        # 2. Find the router associated with that port
        # 3. Find the port associated with this router and on the external net
        # 4. Set up route to the subnet through the port from step 3
        ip_address = None
        for port in ports:
            for fixed_ip in port['fixed_ips']:
                if fixed_ip['subnet_id'] == subnet_id and fixed_ip['ip_address'] == gw_ip:
                    gw_port = port
                    router_id = gw_port['device_id']
                    router = self.shell.quantum.show_router(router_id)['router']
                    if router and router.get('external_gateway_info'):
                        ext_net = router['external_gateway_info']['network_id']
                        for port in ports:
                            if port['device_id'] == router_id and port['network_id'] == ext_net:
                                ip_address = port['fixed_ips'][0]['ip_address']

        if ip_address:
            # check if external route already exists
            route_exists = False
            if routes:
                for route in routes:
                    if subnet['cidr'] in route and ip_address in route:
                        route_exists = True
            if not route_exists:
                cmd = "route add -net %s dev br-ex gw %s" % (subnet['cidr'], ip_address)
                s, o = commands.getstatusoutput(cmd)
                #print cmd, "\n", s, o

        return 1

    def delete_external_route(self, subnet):
        ports = self.shell.quantum.list_ports()['ports']

        gw_ip = subnet['gateway_ip']
        subnet_id = subnet['id']

        # 1. Find the port associated with the subnet's gateway
        # 2. Find the router associated with that port
        # 3. Find the port associated with this router and on the external net
        # 4. Set up route to the subnet through the port from step 3
        ip_address = None
        for port in ports:
            for fixed_ip in port['fixed_ips']:
                if fixed_ip['subnet_id'] == subnet_id and fixed_ip['ip_address'] == gw_ip:
                    gw_port = port
                    router_id = gw_port['device_id']
                    router = self.shell.quantum.show_router(router_id)['router']
                    ext_net = router['external_gateway_info']['network_id']
                    for port in ports:
                        if port['device_id'] == router_id and port['network_id'] == ext_net:
                            ip_address = port['fixed_ips'][0]['ip_address']

        if ip_address:
            cmd = "route delete -net %s" % (subnet['cidr'])
            commands.getstatusoutput(cmd)
             
        return 1
    
    def create_keypair(self, name, public_key):
        keys = self.shell.nova.keypairs.findall(name=name)
        if keys:
            key = keys[0]
            # update key     
            if key.public_key != public_key:
                self.delete_keypair(key.id)
                key = self.shell.nova.keypairs.create(name=name, public_key=public_key)
        else:
            key = self.shell.nova.keypairs.create(name=name, public_key=public_key)
        return key

    def delete_keypair(self, id):
        keys = self.shell.nova.keypairs.findall(id=id)
        for key in keys:
            self.shell.nova.keypairs.delete(key) 
        return 1

    def get_private_networks(self, tenant=None):
        if not tenant:
            tenant = self.shell.nova.tenant
        tenant = self.shell.keystone.tenants.find(name=tenant)
        search_opts = {"tenant_id": tenant.id, "shared": False}
        private_networks = self.shell.quantum.list_networks(**search_opts)
        return private_networks

    def get_shared_networks(self):
        search_opts = {"shared": True}
        shared_networks = self.shell.quantum.list_networks(**search_opts)
        return shared_networks

    def get_network_subnet(self, network_id):
        subnet_id = None
        subnet = None
        if network_id:
            os_networks = self.shell.quantum.list_networks(id=network_id)["networks"]
            if os_networks:
                os_network = os_networks[0]
                if os_network['subnets']:
                    subnet_id = os_network['subnets'][0]
                    os_subnets = self.shell.quantum.list_subnets(id=subnet_id)['subnets']
                    if os_subnets:
                        subnet = os_subnets[0]['cidr']

        return (subnet_id, subnet)

    def spawn_instance(self, name, key_name=None, hostname=None, image_id=None, security_group=None, pubkeys=[], nics=None):
        flavor_name = self.config.nova_default_flavor
        flavor = self.shell.nova.flavors.find(name=flavor_name)
        #if not image:
        #    image = self.config.nova_default_imave
        if not security_group:
            security_group = self.config.nova_default_security_group 

        files = {}
        if pubkeys:    
            files['/root/.ssh/authorized_keys'] = "\n".join(pubkeys)
       
        hints = {}
        availability_zone = None
        if hostname:
            availability_zone = 'nova:%s' % hostname
        server = self.shell.nova.servers.create(
                                            name=name,
                                            key_name = key_name,
                                            flavor=flavor.id,
                                            image=image_id,
                                            security_group = security_group,
                                            files=files,
                                            scheduler_hints=hints,
                                            availability_zone=availability_zone,
                                            nics=nics)
        return server

    def destroy_instance(self, id):
        if (self.shell.nova.tenant=="admin"):
            # findall() is implemented as a list() followed by a python search of the
            # list. Since findall() doesn't accept "all_tenants", we do this using
            # list() ourselves. This allows us to delete an instance as admin.
            servers = self.shell.nova.servers.list(search_opts={"all_tenants": True})
        else:
            servers = self.shell.nova.servers.list()
        for server in servers:
            if server.id == id:
                result=self.shell.nova.servers.delete(server)

    def update_instance_metadata(self, id, metadata):
        servers = self.shell.nova.servers.findall(id=id)
        for server in servers:
            self.shell.nova.servers.set_meta(server, metadata)
            # note: set_meta() returns a broken Server() object. Don't try to
            # print it in the shell or it will fail in __repr__.

    def delete_instance_metadata(self, id, metadata):
        # note: metadata is a dict. Only the keys matter, not the values.
        servers = self.shell.nova.servers.findall(id=id)
        for server in servers:
            self.shell.nova.servers.delete_meta(server, metadata)

